import { Component, EventEmitter, Input, Output } from '@angular/core';
import { RunView } from '@memberjunction/core';
import { APIKeysEngineBase, parseAPIScopeUIConfig } from '@memberjunction/api-keys-base';
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
import * as i3 from "@memberjunction/ng-ui-components";
import * as i4 from "@memberjunction/ng-shared-generic";
function APIKeyListComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
    const _r1 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "button", 22);
    i0.ɵɵlistener("click", function APIKeyListComponent_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.clearSearch()); });
    i0.ɵɵelement(1, "i", 23);
    i0.ɵɵelementEnd();
} }
function APIKeyListComponent_Conditional_45_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-loading", 19);
} }
function APIKeyListComponent_Conditional_46_For_23_Conditional_16_For_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 57);
    i0.ɵɵelement(1, "i");
    i0.ɵɵelementStart(2, "span", 58);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const cat_r6 = i0.ɵɵnextContext().$implicit;
    i0.ɵɵstyleProp("background-color", cat_r6.color + "15")("color", cat_r6.color);
    i0.ɵɵproperty("title", cat_r6.category + ": " + cat_r6.count + " scope(s)");
    i0.ɵɵadvance();
    i0.ɵɵclassMap(cat_r6.icon);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(cat_r6.count);
} }
function APIKeyListComponent_Conditional_46_For_23_Conditional_16_For_3_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, APIKeyListComponent_Conditional_46_For_23_Conditional_16_For_3_Conditional_0_Template, 4, 8, "span", 56);
} if (rf & 2) {
    const ɵ$index_154_r7 = ctx.$index;
    i0.ɵɵconditional(ɵ$index_154_r7 < 3 ? 0 : -1);
} }
function APIKeyListComponent_Conditional_46_For_23_Conditional_16_Conditional_4_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 54);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const key_r5 = i0.ɵɵnextContext(2).$implicit;
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" +", ctx_r1.getScopeInfo(key_r5).categories.length - 3, " ");
} }
function APIKeyListComponent_Conditional_46_For_23_Conditional_16_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 45)(1, "div", 53);
    i0.ɵɵrepeaterCreate(2, APIKeyListComponent_Conditional_46_For_23_Conditional_16_For_3_Template, 1, 1, null, null, i0.ɵɵrepeaterTrackByIdentity);
    i0.ɵɵconditionalCreate(4, APIKeyListComponent_Conditional_46_For_23_Conditional_16_Conditional_4_Template, 2, 1, "span", 54);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "span", 55);
    i0.ɵɵtext(6);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const key_r5 = i0.ɵɵnextContext().$implicit;
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance(2);
    i0.ɵɵrepeater(ctx_r1.getScopeInfo(key_r5).categories);
    i0.ɵɵadvance(2);
    i0.ɵɵconditional(ctx_r1.getScopeInfo(key_r5).categories.length > 3 ? 4 : -1);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1(" ", ctx_r1.getScopeInfo(key_r5).count, " total ");
} }
function APIKeyListComponent_Conditional_46_For_23_Conditional_17_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 46);
    i0.ɵɵelement(1, "i", 59);
    i0.ɵɵtext(2, " None ");
    i0.ɵɵelementEnd();
} }
function APIKeyListComponent_Conditional_46_For_23_Template(rf, ctx) { if (rf & 1) {
    const _r4 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 34);
    i0.ɵɵlistener("click", function APIKeyListComponent_Conditional_46_For_23_Template_div_click_0_listener() { const key_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.selectKey(key_r5)); });
    i0.ɵɵelementStart(1, "div", 35)(2, "div", 36);
    i0.ɵɵelement(3, "i", 37);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "div", 38)(5, "span", 39);
    i0.ɵɵtext(6);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(7, "code", 40);
    i0.ɵɵtext(8);
    i0.ɵɵelementEnd()()();
    i0.ɵɵelementStart(9, "div", 41)(10, "span", 42);
    i0.ɵɵtext(11);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(12, "div", 43)(13, "span", 44);
    i0.ɵɵtext(14);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(15, "div", 28);
    i0.ɵɵconditionalCreate(16, APIKeyListComponent_Conditional_46_For_23_Conditional_16_Template, 7, 2, "div", 45);
    i0.ɵɵconditionalCreate(17, APIKeyListComponent_Conditional_46_For_23_Conditional_17_Template, 3, 0, "span", 46);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(18, "div", 47)(19, "span", 48);
    i0.ɵɵtext(20);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(21, "div", 49)(22, "span", 50);
    i0.ɵɵtext(23);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(24, "div", 51)(25, "span", 52);
    i0.ɵɵtext(26);
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const key_r5 = ctx.$implicit;
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance(2);
    i0.ɵɵclassProp("active", key_r5.Status === "Active");
    i0.ɵɵadvance(4);
    i0.ɵɵtextInterpolate(key_r5.Label);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1("...", key_r5.Hash.slice(-12));
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(key_r5.User);
    i0.ɵɵadvance(2);
    i0.ɵɵclassProp("active", key_r5.Status === "Active")("revoked", key_r5.Status === "Revoked");
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" ", key_r5.Status, " ");
    i0.ɵɵadvance(2);
    i0.ɵɵconditional(ctx_r1.getScopeInfo(key_r5).count > 0 ? 16 : -1);
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r1.getScopeInfo(key_r5).count === 0 ? 17 : -1);
    i0.ɵɵadvance(2);
    i0.ɵɵproperty("ngClass", ctx_r1.getExpirationClass(key_r5));
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" ", ctx_r1.formatExpiration(key_r5.ExpiresAt), " ");
    i0.ɵɵadvance(2);
    i0.ɵɵclassProp("never", !key_r5.LastUsedAt);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" ", ctx_r1.formatDate(key_r5.LastUsedAt), " ");
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(ctx_r1.formatDate(key_r5.__mj_CreatedAt));
} }
function APIKeyListComponent_Conditional_46_Conditional_24_Template(rf, ctx) { if (rf & 1) {
    const _r8 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "mj-empty-state", 60);
    i0.ɵɵlistener("Action", function APIKeyListComponent_Conditional_46_Conditional_24_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.requestCreate()); });
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵproperty("Variant", ctx_r1.SearchText || ctx_r1.Filter !== "all" ? "no-results" : "empty")("Title", ctx_r1.EmptyStateTitle)("ActionText", !ctx_r1.SearchText && ctx_r1.Filter === "all" ? "Generate Your First Key" : "");
} }
function APIKeyListComponent_Conditional_46_Template(rf, ctx) { if (rf & 1) {
    const _r3 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 20)(1, "div", 24)(2, "div", 25);
    i0.ɵɵlistener("click", function APIKeyListComponent_Conditional_46_Template_div_click_2_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleSort("Label")); });
    i0.ɵɵtext(3, " Key ");
    i0.ɵɵelement(4, "i");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "div", 26);
    i0.ɵɵlistener("click", function APIKeyListComponent_Conditional_46_Template_div_click_5_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleSort("User")); });
    i0.ɵɵtext(6, " Owner ");
    i0.ɵɵelement(7, "i");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(8, "div", 27);
    i0.ɵɵlistener("click", function APIKeyListComponent_Conditional_46_Template_div_click_8_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleSort("Status")); });
    i0.ɵɵtext(9, " Status ");
    i0.ɵɵelement(10, "i");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(11, "div", 28);
    i0.ɵɵtext(12, " Scopes ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(13, "div", 29);
    i0.ɵɵlistener("click", function APIKeyListComponent_Conditional_46_Template_div_click_13_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleSort("ExpiresAt")); });
    i0.ɵɵtext(14, " Expires ");
    i0.ɵɵelement(15, "i");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(16, "div", 30);
    i0.ɵɵlistener("click", function APIKeyListComponent_Conditional_46_Template_div_click_16_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleSort("LastUsedAt")); });
    i0.ɵɵtext(17, " Last Used ");
    i0.ɵɵelement(18, "i");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(19, "div", 31);
    i0.ɵɵlistener("click", function APIKeyListComponent_Conditional_46_Template_div_click_19_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleSort("__mj_CreatedAt")); });
    i0.ɵɵtext(20, " Created ");
    i0.ɵɵelement(21, "i");
    i0.ɵɵelementEnd()();
    i0.ɵɵrepeaterCreate(22, APIKeyListComponent_Conditional_46_For_23_Template, 27, 18, "div", 32, i0.ɵɵrepeaterTrackByIdentity);
    i0.ɵɵconditionalCreate(24, APIKeyListComponent_Conditional_46_Conditional_24_Template, 1, 3, "mj-empty-state", 33);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext();
    i0.ɵɵadvance(4);
    i0.ɵɵclassMap(ctx_r1.getSortIcon("Label"));
    i0.ɵɵadvance(3);
    i0.ɵɵclassMap(ctx_r1.getSortIcon("User"));
    i0.ɵɵadvance(3);
    i0.ɵɵclassMap(ctx_r1.getSortIcon("Status"));
    i0.ɵɵadvance(5);
    i0.ɵɵclassMap(ctx_r1.getSortIcon("ExpiresAt"));
    i0.ɵɵadvance(3);
    i0.ɵɵclassMap(ctx_r1.getSortIcon("LastUsedAt"));
    i0.ɵɵadvance(3);
    i0.ɵɵclassMap(ctx_r1.getSortIcon("__mj_CreatedAt"));
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r1.getPaginatedKeys());
    i0.ɵɵadvance(2);
    i0.ɵɵconditional(ctx_r1.FilteredKeys.length === 0 ? 24 : -1);
} }
function APIKeyListComponent_Conditional_47_For_7_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    const _r10 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "button", 68);
    i0.ɵɵlistener("click", function APIKeyListComponent_Conditional_47_For_7_Conditional_0_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const page_r11 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.goToPage(page_r11)); });
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const page_r11 = i0.ɵɵnextContext().$implicit;
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵclassProp("active", page_r11 === ctx_r1.CurrentPage);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" ", page_r11, " ");
} }
function APIKeyListComponent_Conditional_47_For_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 67);
    i0.ɵɵtext(1, "...");
    i0.ɵɵelementEnd();
} }
function APIKeyListComponent_Conditional_47_For_7_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, APIKeyListComponent_Conditional_47_For_7_Conditional_0_Template, 2, 3, "button", 66);
    i0.ɵɵconditionalCreate(1, APIKeyListComponent_Conditional_47_For_7_Conditional_1_Template, 2, 0, "span", 67);
} if (rf & 2) {
    const page_r11 = ctx.$implicit;
    i0.ɵɵconditional(page_r11 > 0 ? 0 : -1);
    i0.ɵɵadvance();
    i0.ɵɵconditional(page_r11 === -1 ? 1 : -1);
} }
function APIKeyListComponent_Conditional_47_Template(rf, ctx) { if (rf & 1) {
    const _r9 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 21)(1, "div", 61);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 62)(4, "button", 63);
    i0.ɵɵlistener("click", function APIKeyListComponent_Conditional_47_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.goToPage(ctx_r1.CurrentPage - 1)); });
    i0.ɵɵelement(5, "i", 64);
    i0.ɵɵelementEnd();
    i0.ɵɵrepeaterCreate(6, APIKeyListComponent_Conditional_47_For_7_Template, 2, 2, null, null, i0.ɵɵrepeaterTrackByIdentity);
    i0.ɵɵelementStart(8, "button", 63);
    i0.ɵɵlistener("click", function APIKeyListComponent_Conditional_47_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.goToPage(ctx_r1.CurrentPage + 1)); });
    i0.ɵɵelement(9, "i", 65);
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext();
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate3(" Showing ", (ctx_r1.CurrentPage - 1) * ctx_r1.PageSize + 1, " - ", ctx_r1.Math.min(ctx_r1.CurrentPage * ctx_r1.PageSize, ctx_r1.FilteredKeys.length), " of ", ctx_r1.FilteredKeys.length, " ");
    i0.ɵɵadvance(2);
    i0.ɵɵproperty("disabled", ctx_r1.CurrentPage === 1);
    i0.ɵɵadvance(2);
    i0.ɵɵrepeater(ctx_r1.getPageNumbers());
    i0.ɵɵadvance(2);
    i0.ɵɵproperty("disabled", ctx_r1.CurrentPage === ctx_r1.getTotalPages());
} }
/**
 * List view component for displaying and filtering API keys
 */
export class APIKeyListComponent extends BaseAngularComponent {
    Filter = 'all';
    KeySelected = new EventEmitter();
    CreateRequested = new EventEmitter();
    // Expose Math for template
    Math = Math;
    // Data
    AllKeys = [];
    FilteredKeys = [];
    IsLoading = true;
    // Search
    SearchText = '';
    // Sorting
    SortField = '__mj_CreatedAt';
    SortDirection = 'desc';
    // Pagination
    PageSize = 20;
    CurrentPage = 1;
    // Statistics
    Stats = {
        total: 0,
        active: 0,
        revoked: 0,
        expiring: 0,
        expired: 0,
        neverUsed: 0
    };
    // Scope counts per key
    KeyScopeMap = new Map();
    AllScopes = [];
    // Default UI config for categories without explicit configuration
    defaultUIConfig = {
        icon: 'fa-solid fa-ellipsis',
        color: 'var(--mj-text-muted)'
    };
    // Dynamic category UI config built from root scopes
    categoryUIConfigs = new Map();
    async ngOnInit() {
        await this.loadKeys();
    }
    async ngOnChanges(changes) {
        if (changes['Filter'] && !changes['Filter'].firstChange) {
            this.applyFilters();
        }
    }
    /**
     * Load all API keys
     */
    async loadKeys() {
        this.IsLoading = true;
        try {
            const rv = RunView.FromMetadataProvider(this.ProviderToUse);
            const base = APIKeysEngineBase.Instance;
            // Load keys and key-scope assignments (scopes from cache)
            const [keysResult, keyScopesResult] = await rv.RunViews([
                {
                    EntityName: 'MJ: API Keys',
                    OrderBy: '__mj_CreatedAt DESC',
                    ResultType: 'entity_object'
                },
                {
                    EntityName: 'MJ: API Key Scopes',
                    ResultType: 'entity_object'
                }
            ]);
            if (keysResult.Success) {
                this.AllKeys = keysResult.Results;
                this.AllScopes = base.Scopes;
                // Build category UI config from root scopes
                this.categoryUIConfigs.clear();
                for (const scope of this.AllScopes) {
                    if (!scope.ParentID) {
                        const uiConfig = parseAPIScopeUIConfig(scope);
                        this.categoryUIConfigs.set(scope.Category, {
                            icon: uiConfig.icon || this.defaultUIConfig.icon,
                            color: uiConfig.color || this.defaultUIConfig.color
                        });
                    }
                }
                // Build scope lookup map
                const scopeMap = new Map();
                for (const scope of this.AllScopes) {
                    scopeMap.set(scope.ID, scope);
                }
                // Build key scope counts with category breakdown
                this.KeyScopeMap.clear();
                if (keyScopesResult.Success) {
                    const keyScopes = keyScopesResult.Results;
                    const keyToScopes = new Map();
                    for (const ks of keyScopes) {
                        if (!keyToScopes.has(ks.APIKeyID)) {
                            keyToScopes.set(ks.APIKeyID, { names: [], categories: new Map() });
                        }
                        const scope = scopeMap.get(ks.ScopeID);
                        if (scope) {
                            const keyData = keyToScopes.get(ks.APIKeyID);
                            keyData.names.push(scope.FullPath || scope.Name);
                            const category = scope.Category || 'Other';
                            keyData.categories.set(category, (keyData.categories.get(category) || 0) + 1);
                        }
                    }
                    for (const [keyId, data] of keyToScopes.entries()) {
                        const categories = Array.from(data.categories.entries())
                            .map(([category, count]) => {
                            const config = this.categoryUIConfigs.get(category) || this.defaultUIConfig;
                            return {
                                category,
                                count,
                                color: config.color,
                                icon: config.icon
                            };
                        })
                            .sort((a, b) => b.count - a.count);
                        this.KeyScopeMap.set(keyId, {
                            count: data.names.length,
                            preview: data.names.slice(0, 3),
                            categories
                        });
                    }
                }
                this.calculateStats();
                this.applyFilters();
            }
        }
        catch (error) {
            console.error('Error loading API keys:', error);
        }
        finally {
            this.IsLoading = false;
        }
    }
    /**
     * Get scope info for a key
     */
    getScopeInfo(key) {
        return this.KeyScopeMap.get(key.ID) || { count: 0, preview: [], categories: [] };
    }
    /**
     * Calculate statistics
     */
    calculateStats() {
        const now = new Date();
        const thirtyDaysFromNow = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000);
        this.Stats = {
            total: this.AllKeys.length,
            active: this.AllKeys.filter(k => k.Status === 'Active').length,
            revoked: this.AllKeys.filter(k => k.Status === 'Revoked').length,
            expiring: this.AllKeys.filter(k => k.Status === 'Active' &&
                k.ExpiresAt &&
                new Date(k.ExpiresAt) > now &&
                new Date(k.ExpiresAt) < thirtyDaysFromNow).length,
            expired: this.AllKeys.filter(k => k.ExpiresAt && new Date(k.ExpiresAt) < now).length,
            neverUsed: this.AllKeys.filter(k => k.Status === 'Active' && !k.LastUsedAt).length
        };
    }
    /**
     * Apply filters and sorting
     */
    applyFilters() {
        const now = new Date();
        const thirtyDaysFromNow = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000);
        let filtered = [...this.AllKeys];
        // Apply status filter
        switch (this.Filter) {
            case 'active':
                filtered = filtered.filter(k => k.Status === 'Active');
                break;
            case 'revoked':
                filtered = filtered.filter(k => k.Status === 'Revoked');
                break;
            case 'expiring':
                filtered = filtered.filter(k => k.Status === 'Active' &&
                    k.ExpiresAt &&
                    new Date(k.ExpiresAt) > now &&
                    new Date(k.ExpiresAt) < thirtyDaysFromNow);
                break;
            case 'expired':
                filtered = filtered.filter(k => k.ExpiresAt && new Date(k.ExpiresAt) < now);
                break;
            case 'never-used':
                filtered = filtered.filter(k => k.Status === 'Active' && !k.LastUsedAt);
                break;
        }
        // Apply search filter
        if (this.SearchText.trim()) {
            const search = this.SearchText.toLowerCase();
            filtered = filtered.filter(k => k.Label.toLowerCase().includes(search) ||
                (k.Description && k.Description.toLowerCase().includes(search)) ||
                k.User.toLowerCase().includes(search) ||
                k.Hash.toLowerCase().includes(search));
        }
        // Apply sorting
        filtered.sort((a, b) => {
            let aVal = null;
            let bVal = null;
            switch (this.SortField) {
                case 'Label':
                    aVal = a.Label.toLowerCase();
                    bVal = b.Label.toLowerCase();
                    break;
                case 'Status':
                    aVal = a.Status;
                    bVal = b.Status;
                    break;
                case 'User':
                    aVal = a.User.toLowerCase();
                    bVal = b.User.toLowerCase();
                    break;
                case 'LastUsedAt':
                    aVal = a.LastUsedAt ? new Date(a.LastUsedAt).getTime() : 0;
                    bVal = b.LastUsedAt ? new Date(b.LastUsedAt).getTime() : 0;
                    break;
                case 'ExpiresAt':
                    aVal = a.ExpiresAt ? new Date(a.ExpiresAt).getTime() : Number.MAX_SAFE_INTEGER;
                    bVal = b.ExpiresAt ? new Date(b.ExpiresAt).getTime() : Number.MAX_SAFE_INTEGER;
                    break;
                case '__mj_CreatedAt':
                    aVal = new Date(a.__mj_CreatedAt).getTime();
                    bVal = new Date(b.__mj_CreatedAt).getTime();
                    break;
            }
            if (aVal < bVal)
                return this.SortDirection === 'asc' ? -1 : 1;
            if (aVal > bVal)
                return this.SortDirection === 'asc' ? 1 : -1;
            return 0;
        });
        this.FilteredKeys = filtered;
        this.CurrentPage = 1;
    }
    /**
     * Handle search input
     */
    onSearch() {
        this.applyFilters();
    }
    /**
     * Clear search
     */
    clearSearch() {
        this.SearchText = '';
        this.applyFilters();
    }
    /** Dynamic title for the empty state — reflects search vs filter vs truly-empty. */
    get EmptyStateTitle() {
        if (this.SearchText) {
            return `No keys matching "${this.SearchText}"`;
        }
        if (this.Filter !== 'all') {
            return `No ${this.Filter} keys found`;
        }
        return 'No API keys created yet';
    }
    /**
     * Set filter
     */
    setFilter(filter) {
        this.Filter = filter;
        this.applyFilters();
    }
    /**
     * Toggle sort
     */
    toggleSort(field) {
        if (this.SortField === field) {
            this.SortDirection = this.SortDirection === 'asc' ? 'desc' : 'asc';
        }
        else {
            this.SortField = field;
            this.SortDirection = field === 'Label' ? 'asc' : 'desc';
        }
        this.applyFilters();
    }
    /**
     * Get sort icon class
     */
    getSortIcon(field) {
        if (this.SortField !== field)
            return 'fa-solid fa-sort';
        return this.SortDirection === 'asc' ? 'fa-solid fa-sort-up' : 'fa-solid fa-sort-down';
    }
    /**
     * Get paginated keys
     */
    getPaginatedKeys() {
        const start = (this.CurrentPage - 1) * this.PageSize;
        return this.FilteredKeys.slice(start, start + this.PageSize);
    }
    /**
     * Get total pages
     */
    getTotalPages() {
        return Math.ceil(this.FilteredKeys.length / this.PageSize);
    }
    /**
     * Go to page
     */
    goToPage(page) {
        if (page >= 1 && page <= this.getTotalPages()) {
            this.CurrentPage = page;
        }
    }
    /**
     * Get page numbers to display
     */
    getPageNumbers() {
        const total = this.getTotalPages();
        const current = this.CurrentPage;
        const pages = [];
        if (total <= 7) {
            for (let i = 1; i <= total; i++)
                pages.push(i);
        }
        else {
            pages.push(1);
            if (current > 3)
                pages.push(-1); // ellipsis
            const start = Math.max(2, current - 1);
            const end = Math.min(total - 1, current + 1);
            for (let i = start; i <= end; i++)
                pages.push(i);
            if (current < total - 2)
                pages.push(-1); // ellipsis
            pages.push(total);
        }
        return pages;
    }
    /**
     * Select a key
     */
    selectKey(key) {
        this.KeySelected.emit(key);
    }
    /**
     * Request key creation
     */
    requestCreate() {
        this.CreateRequested.emit();
    }
    /**
     * Format date for display
     */
    formatDate(date) {
        if (!date)
            return 'Never';
        const now = new Date();
        const d = new Date(date);
        const diff = now.getTime() - d.getTime();
        const days = Math.floor(diff / 86400000);
        if (days === 0) {
            const hours = Math.floor(diff / 3600000);
            if (hours === 0) {
                const minutes = Math.floor(diff / 60000);
                return minutes < 1 ? 'Just now' : `${minutes}m ago`;
            }
            return `${hours}h ago`;
        }
        if (days === 1)
            return 'Yesterday';
        if (days < 7)
            return `${days} days ago`;
        return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
    }
    /**
     * Format expiration for display
     */
    formatExpiration(date) {
        if (!date)
            return 'Never';
        const now = new Date();
        const d = new Date(date);
        const diff = d.getTime() - now.getTime();
        if (diff < 0)
            return 'Expired';
        const days = Math.floor(diff / 86400000);
        if (days === 0)
            return 'Today';
        if (days === 1)
            return 'Tomorrow';
        if (days < 30)
            return `${days} days`;
        return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
    }
    /**
     * Get expiration status class
     */
    getExpirationClass(key) {
        if (!key.ExpiresAt)
            return 'never';
        const now = new Date();
        const expiresAt = new Date(key.ExpiresAt);
        const diff = expiresAt.getTime() - now.getTime();
        const days = Math.floor(diff / 86400000);
        if (diff < 0)
            return 'expired';
        if (days < 7)
            return 'critical';
        if (days < 30)
            return 'warning';
        return 'ok';
    }
    /**
     * Get filter count
     */
    getFilterCount(filter) {
        switch (filter) {
            case 'all': return this.Stats.total;
            case 'active': return this.Stats.active;
            case 'revoked': return this.Stats.revoked;
            case 'expiring': return this.Stats.expiring;
            case 'expired': return this.Stats.expired;
            case 'never-used': return this.Stats.neverUsed;
        }
    }
    static ɵfac = /*@__PURE__*/ (() => { let ɵAPIKeyListComponent_BaseFactory; return function APIKeyListComponent_Factory(__ngFactoryType__) { return (ɵAPIKeyListComponent_BaseFactory || (ɵAPIKeyListComponent_BaseFactory = i0.ɵɵgetInheritedFactory(APIKeyListComponent)))(__ngFactoryType__ || APIKeyListComponent); }; })();
    static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: APIKeyListComponent, selectors: [["mj-api-key-list"]], inputs: { Filter: "Filter" }, outputs: { KeySelected: "KeySelected", CreateRequested: "CreateRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 48, vars: 29, consts: [[1, "list-container"], [1, "list-header"], [1, "header-left"], [1, "count-badge"], [1, "header-right"], [1, "search-box"], [1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search keys...", 3, "ngModelChange", "ngModel"], [1, "clear-search"], [1, "create-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "filter-tabs"], [1, "filter-tab", 3, "click"], [1, "tab-count"], [1, "fa-solid", "fa-check-circle", "status-active"], [1, "fa-solid", "fa-clock", "status-warning"], [1, "fa-solid", "fa-circle-exclamation", "status-danger"], [1, "fa-solid", "fa-question-circle", "status-info"], [1, "fa-solid", "fa-ban", "status-revoked"], ["text", "Loading API keys..."], [1, "key-grid"], [1, "pagination"], [1, "clear-search", 3, "click"], [1, "fa-solid", "fa-times"], [1, "grid-header"], [1, "col-key", "sortable", 3, "click"], [1, "col-owner", "sortable", 3, "click"], [1, "col-status", "sortable", 3, "click"], [1, "col-scopes"], [1, "col-expires", "sortable", 3, "click"], [1, "col-used", "sortable", 3, "click"], [1, "col-created", "sortable", 3, "click"], [1, "grid-row"], ["Icon", "fa-solid fa-key", "ActionIcon", "fa-solid fa-plus", 3, "Variant", "Title", "ActionText"], [1, "grid-row", 3, "click"], [1, "col-key"], [1, "key-icon"], [1, "fa-solid", "fa-key"], [1, "key-details"], [1, "key-label"], [1, "key-hash"], [1, "col-owner"], [1, "owner-name"], [1, "col-status"], [1, "status-badge"], [1, "scopes-display"], [1, "no-scopes"], [1, "col-expires"], [1, "expires-value", 3, "ngClass"], [1, "col-used"], [1, "used-value"], [1, "col-created"], [1, "created-value"], [1, "scope-badges"], [1, "scope-more"], [1, "scopes-total"], [1, "scope-badge", 3, "backgroundColor", "color", "title"], [1, "scope-badge", 3, "title"], [1, "badge-count"], [1, "fa-solid", "fa-shield-xmark"], ["Icon", "fa-solid fa-key", "ActionIcon", "fa-solid fa-plus", 3, "Action", "Variant", "Title", "ActionText"], [1, "page-info"], [1, "page-buttons"], [1, "page-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-left"], [1, "fa-solid", "fa-chevron-right"], [1, "page-btn", 3, "active"], [1, "page-ellipsis"], [1, "page-btn", 3, "click"]], template: function APIKeyListComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "h3");
            i0.ɵɵtext(4, "API Keys");
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(5, "span", 3);
            i0.ɵɵtext(6);
            i0.ɵɵelementEnd()();
            i0.ɵɵelementStart(7, "div", 4)(8, "div", 5);
            i0.ɵɵelement(9, "i", 6);
            i0.ɵɵelementStart(10, "input", 7);
            i0.ɵɵtwoWayListener("ngModelChange", function APIKeyListComponent_Template_input_ngModelChange_10_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.SearchText, $event) || (ctx.SearchText = $event); return $event; });
            i0.ɵɵlistener("ngModelChange", function APIKeyListComponent_Template_input_ngModelChange_10_listener() { return ctx.onSearch(); });
            i0.ɵɵelementEnd();
            i0.ɵɵconditionalCreate(11, APIKeyListComponent_Conditional_11_Template, 2, 0, "button", 8);
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(12, "button", 9);
            i0.ɵɵlistener("click", function APIKeyListComponent_Template_button_click_12_listener() { return ctx.requestCreate(); });
            i0.ɵɵelement(13, "i", 10);
            i0.ɵɵtext(14, " Generate Key ");
            i0.ɵɵelementEnd()()();
            i0.ɵɵelementStart(15, "div", 11)(16, "button", 12);
            i0.ɵɵlistener("click", function APIKeyListComponent_Template_button_click_16_listener() { return ctx.setFilter("all"); });
            i0.ɵɵtext(17, " All ");
            i0.ɵɵelementStart(18, "span", 13);
            i0.ɵɵtext(19);
            i0.ɵɵelementEnd()();
            i0.ɵɵelementStart(20, "button", 12);
            i0.ɵɵlistener("click", function APIKeyListComponent_Template_button_click_20_listener() { return ctx.setFilter("active"); });
            i0.ɵɵelement(21, "i", 14);
            i0.ɵɵtext(22, " Active ");
            i0.ɵɵelementStart(23, "span", 13);
            i0.ɵɵtext(24);
            i0.ɵɵelementEnd()();
            i0.ɵɵelementStart(25, "button", 12);
            i0.ɵɵlistener("click", function APIKeyListComponent_Template_button_click_25_listener() { return ctx.setFilter("expiring"); });
            i0.ɵɵelement(26, "i", 15);
            i0.ɵɵtext(27, " Expiring Soon ");
            i0.ɵɵelementStart(28, "span", 13);
            i0.ɵɵtext(29);
            i0.ɵɵelementEnd()();
            i0.ɵɵelementStart(30, "button", 12);
            i0.ɵɵlistener("click", function APIKeyListComponent_Template_button_click_30_listener() { return ctx.setFilter("expired"); });
            i0.ɵɵelement(31, "i", 16);
            i0.ɵɵtext(32, " Expired ");
            i0.ɵɵelementStart(33, "span", 13);
            i0.ɵɵtext(34);
            i0.ɵɵelementEnd()();
            i0.ɵɵelementStart(35, "button", 12);
            i0.ɵɵlistener("click", function APIKeyListComponent_Template_button_click_35_listener() { return ctx.setFilter("never-used"); });
            i0.ɵɵelement(36, "i", 17);
            i0.ɵɵtext(37, " Never Used ");
            i0.ɵɵelementStart(38, "span", 13);
            i0.ɵɵtext(39);
            i0.ɵɵelementEnd()();
            i0.ɵɵelementStart(40, "button", 12);
            i0.ɵɵlistener("click", function APIKeyListComponent_Template_button_click_40_listener() { return ctx.setFilter("revoked"); });
            i0.ɵɵelement(41, "i", 18);
            i0.ɵɵtext(42, " Revoked ");
            i0.ɵɵelementStart(43, "span", 13);
            i0.ɵɵtext(44);
            i0.ɵɵelementEnd()()();
            i0.ɵɵconditionalCreate(45, APIKeyListComponent_Conditional_45_Template, 1, 0, "mj-loading", 19);
            i0.ɵɵconditionalCreate(46, APIKeyListComponent_Conditional_46_Template, 25, 13, "div", 20);
            i0.ɵɵconditionalCreate(47, APIKeyListComponent_Conditional_47_Template, 10, 5, "div", 21);
            i0.ɵɵelementEnd();
        } if (rf & 2) {
            i0.ɵɵadvance(6);
            i0.ɵɵtextInterpolate2("", ctx.FilteredKeys.length, " of ", ctx.AllKeys.length);
            i0.ɵɵadvance(4);
            i0.ɵɵtwoWayProperty("ngModel", ctx.SearchText);
            i0.ɵɵadvance();
            i0.ɵɵconditional(ctx.SearchText ? 11 : -1);
            i0.ɵɵadvance(5);
            i0.ɵɵclassProp("active", ctx.Filter === "all");
            i0.ɵɵadvance(3);
            i0.ɵɵtextInterpolate(ctx.Stats.total);
            i0.ɵɵadvance();
            i0.ɵɵclassProp("active", ctx.Filter === "active");
            i0.ɵɵadvance(4);
            i0.ɵɵtextInterpolate(ctx.Stats.active);
            i0.ɵɵadvance();
            i0.ɵɵclassProp("active", ctx.Filter === "expiring")("has-warning", ctx.Stats.expiring > 0);
            i0.ɵɵadvance(4);
            i0.ɵɵtextInterpolate(ctx.Stats.expiring);
            i0.ɵɵadvance();
            i0.ɵɵclassProp("active", ctx.Filter === "expired")("has-danger", ctx.Stats.expired > 0);
            i0.ɵɵadvance(4);
            i0.ɵɵtextInterpolate(ctx.Stats.expired);
            i0.ɵɵadvance();
            i0.ɵɵclassProp("active", ctx.Filter === "never-used");
            i0.ɵɵadvance(4);
            i0.ɵɵtextInterpolate(ctx.Stats.neverUsed);
            i0.ɵɵadvance();
            i0.ɵɵclassProp("active", ctx.Filter === "revoked");
            i0.ɵɵadvance(4);
            i0.ɵɵtextInterpolate(ctx.Stats.revoked);
            i0.ɵɵadvance();
            i0.ɵɵconditional(ctx.IsLoading ? 45 : -1);
            i0.ɵɵadvance();
            i0.ɵɵconditional(!ctx.IsLoading ? 46 : -1);
            i0.ɵɵadvance();
            i0.ɵɵconditional(!ctx.IsLoading && ctx.FilteredKeys.length > ctx.PageSize ? 47 : -1);
        } }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MJEmptyStateComponent, i4.LoadingComponent], styles: [".list-container[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    height: 100%;\n    background: var(--mj-bg-surface);\n    border-radius: 12px;\n    overflow: hidden;\n    box-shadow: var(--mj-shadow-md);\n}\n\n\n\n.list-header[_ngcontent-%COMP%] {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 20px 24px;\n    background: linear-gradient(135deg, var(--mj-color-brand-100) 0%, var(--mj-color-brand-200) 100%);\n    border-bottom: 1px solid var(--mj-color-accent-300);\n}\n\n.header-left[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n}\n\n.header-left[_ngcontent-%COMP%]   h3[_ngcontent-%COMP%] {\n    margin: 0;\n    font-size: 20px;\n    font-weight: 700;\n    color: var(--mj-color-brand-800);\n}\n\n.count-badge[_ngcontent-%COMP%] {\n    padding: 4px 12px;\n    background: rgba(255, 255, 255, 0.7);\n    border-radius: 20px;\n    font-size: 13px;\n    font-weight: 500;\n    color: var(--mj-color-brand-800);\n}\n\n.header-right[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n}\n\n\n\n.search-box[_ngcontent-%COMP%] {\n    position: relative;\n    display: flex;\n    align-items: center;\n}\n\n.search-box[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    position: absolute;\n    left: 12px;\n    color: var(--mj-text-muted);\n    font-size: 14px;\n}\n\n.search-box[_ngcontent-%COMP%]   input[_ngcontent-%COMP%] {\n    width: 260px;\n    padding: 10px 36px;\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 8px;\n    font-size: 14px;\n    transition: all 0.2s ease;\n}\n\n.search-box[_ngcontent-%COMP%]   input[_ngcontent-%COMP%]:focus {\n    outline: none;\n    border-color: var(--mj-brand-primary);\n    box-shadow: var(--mj-focus-ring);\n}\n\n.clear-search[_ngcontent-%COMP%] {\n    position: absolute;\n    right: 8px;\n    width: 24px;\n    height: 24px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    background: var(--mj-border-default);\n    border: none;\n    border-radius: 50%;\n    cursor: pointer;\n    transition: all 0.2s ease;\n}\n\n.clear-search[_ngcontent-%COMP%]:hover {\n    background: var(--mj-color-neutral-300);\n}\n\n.clear-search[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    position: static;\n    font-size: 10px;\n    color: var(--mj-text-secondary);\n}\n\n\n\n.create-btn[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n    padding: 10px 20px;\n    background: var(--mj-brand-primary);\n    border: none;\n    border-radius: 8px;\n    font-size: 14px;\n    font-weight: 600;\n    color: var(--mj-text-inverse);\n    cursor: pointer;\n    transition: all 0.2s ease;\n}\n\n.create-btn[_ngcontent-%COMP%]:hover {\n    transform: translateY(-1px);\n    box-shadow: var(--mj-shadow-brand-md);\n}\n\n\n\n.filter-tabs[_ngcontent-%COMP%] {\n    display: flex;\n    gap: 4px;\n    padding: 0 24px;\n    background: var(--mj-bg-page);\n    border-bottom: 1px solid var(--mj-border-default);\n    overflow-x: auto;\n}\n\n.filter-tab[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n    padding: 14px 16px;\n    background: transparent;\n    border: none;\n    border-bottom: 2px solid transparent;\n    font-size: 13px;\n    font-weight: 500;\n    color: var(--mj-text-secondary);\n    cursor: pointer;\n    white-space: nowrap;\n    transition: all 0.2s ease;\n}\n\n.filter-tab[_ngcontent-%COMP%]:hover {\n    color: var(--mj-text-secondary);\n    background: var(--mj-bg-surface-sunken);\n}\n\n.filter-tab.active[_ngcontent-%COMP%] {\n    color: var(--mj-brand-primary);\n    border-bottom-color: var(--mj-brand-primary);\n}\n\n.filter-tab.has-warning[_ngcontent-%COMP%]   .tab-count[_ngcontent-%COMP%] {\n    background: var(--mj-color-brand-100);\n    color: var(--mj-brand-primary-hover);\n}\n\n.filter-tab.has-danger[_ngcontent-%COMP%]   .tab-count[_ngcontent-%COMP%] {\n    background: var(--mj-color-error-100);\n    color: var(--mj-color-error-600);\n}\n\n.tab-count[_ngcontent-%COMP%] {\n    padding: 2px 8px;\n    background: var(--mj-border-default);\n    border-radius: 10px;\n    font-size: 11px;\n    font-weight: 600;\n}\n\n.status-active[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n.status-warning[_ngcontent-%COMP%] { color: var(--mj-color-warning-500); }\n.status-danger[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.status-info[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n.status-revoked[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n\n\n\n.key-grid[_ngcontent-%COMP%] {\n    flex: 1;\n    overflow-y: auto;\n}\n\n.grid-header[_ngcontent-%COMP%] {\n    display: grid;\n    grid-template-columns: 2fr 1fr 90px 160px 100px 110px 100px;\n    gap: 12px;\n    padding: 14px 24px;\n    background: var(--mj-bg-surface-sunken);\n    border-bottom: 1px solid var(--mj-border-default);\n    font-size: 11px;\n    font-weight: 600;\n    color: var(--mj-text-secondary);\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    position: sticky;\n    top: 0;\n}\n\n.sortable[_ngcontent-%COMP%] {\n    cursor: pointer;\n    display: flex;\n    align-items: center;\n    gap: 6px;\n    transition: color 0.2s ease;\n}\n\n.sortable[_ngcontent-%COMP%]:hover {\n    color: var(--mj-text-secondary);\n}\n\n.sortable[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 10px;\n    opacity: 0.5;\n}\n\n\n\n.grid-row[_ngcontent-%COMP%] {\n    display: grid;\n    grid-template-columns: 2fr 1fr 90px 160px 100px 110px 100px;\n    gap: 12px;\n    padding: 16px 24px;\n    border-bottom: 1px solid var(--mj-bg-surface-sunken);\n    cursor: pointer;\n    transition: background 0.2s ease;\n    align-items: center;\n}\n\n.grid-row[_ngcontent-%COMP%]:hover {\n    background: var(--mj-color-brand-50);\n}\n\n.grid-row[_ngcontent-%COMP%]:last-child {\n    border-bottom: none;\n}\n\n\n\n.col-key[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 14px;\n    min-width: 0;\n}\n\n.key-icon[_ngcontent-%COMP%] {\n    width: 40px;\n    height: 40px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    background: linear-gradient(135deg, var(--mj-text-secondary) 0%, var(--mj-color-neutral-600) 100%);\n    border-radius: 8px;\n    flex-shrink: 0;\n}\n\n.key-icon.active[_ngcontent-%COMP%] {\n    background: var(--mj-brand-primary);\n}\n\n.key-icon[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 16px;\n    color: var(--mj-text-inverse);\n}\n\n.key-details[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    gap: 4px;\n    min-width: 0;\n}\n\n.key-label[_ngcontent-%COMP%] {\n    font-weight: 600;\n    font-size: 14px;\n    color: var(--mj-text-primary);\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n}\n\n.key-hash[_ngcontent-%COMP%] {\n    font-family: 'Fira Code', 'Consolas', monospace;\n    font-size: 11px;\n    color: var(--mj-text-secondary);\n    background: var(--mj-bg-surface-sunken);\n    padding: 2px 6px;\n    border-radius: 4px;\n}\n\n\n\n.owner-name[_ngcontent-%COMP%] {\n    font-size: 14px;\n    color: var(--mj-text-secondary);\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n    display: inline-block;\n    padding: 4px 10px;\n    border-radius: 12px;\n    font-size: 12px;\n    font-weight: 600;\n    text-transform: capitalize;\n}\n\n.status-badge.active[_ngcontent-%COMP%] {\n    background: var(--mj-color-success-100);\n    color: var(--mj-color-success-600);\n}\n\n.status-badge.revoked[_ngcontent-%COMP%] {\n    background: var(--mj-bg-surface-sunken);\n    color: var(--mj-text-secondary);\n}\n\n\n\n.col-scopes[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    gap: 4px;\n    min-width: 0;\n}\n\n.scopes-display[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    gap: 4px;\n}\n\n.scope-badges[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n    flex-wrap: wrap;\n}\n\n.scope-badge[_ngcontent-%COMP%] {\n    display: inline-flex;\n    align-items: center;\n    gap: 4px;\n    padding: 3px 8px;\n    border-radius: 12px;\n    font-size: 11px;\n    font-weight: 600;\n    cursor: default;\n    transition: transform 0.15s ease;\n}\n\n.scope-badge[_ngcontent-%COMP%]:hover {\n    transform: scale(1.05);\n}\n\n.scope-badge[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 10px;\n}\n\n.badge-count[_ngcontent-%COMP%] {\n    font-weight: 700;\n}\n\n.scope-more[_ngcontent-%COMP%] {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    padding: 3px 6px;\n    background: var(--mj-bg-surface-sunken);\n    border-radius: 12px;\n    font-size: 10px;\n    font-weight: 600;\n    color: var(--mj-text-secondary);\n}\n\n.scopes-total[_ngcontent-%COMP%] {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n.no-scopes[_ngcontent-%COMP%] {\n    display: inline-flex;\n    align-items: center;\n    gap: 4px;\n    font-size: 12px;\n    color: var(--mj-color-neutral-300);\n}\n\n.no-scopes[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 11px;\n}\n\n\n\n.expires-value[_ngcontent-%COMP%] {\n    font-size: 13px;\n}\n\n.expires-value.never[_ngcontent-%COMP%] {\n    color: var(--mj-text-secondary);\n}\n\n.expires-value.ok[_ngcontent-%COMP%] {\n    color: var(--mj-color-success-600);\n}\n\n.expires-value.warning[_ngcontent-%COMP%] {\n    color: var(--mj-brand-primary-hover);\n    font-weight: 500;\n}\n\n.expires-value.critical[_ngcontent-%COMP%] {\n    color: var(--mj-color-error-600);\n    font-weight: 600;\n}\n\n.expires-value.expired[_ngcontent-%COMP%] {\n    color: var(--mj-color-error-600);\n    font-weight: 600;\n}\n\n\n\n.used-value[_ngcontent-%COMP%] {\n    font-size: 13px;\n    color: var(--mj-text-secondary);\n}\n\n.used-value.never[_ngcontent-%COMP%] {\n    color: var(--mj-text-muted);\n    font-style: italic;\n}\n\n\n\n.created-value[_ngcontent-%COMP%] {\n    font-size: 13px;\n    color: var(--mj-text-secondary);\n}\n\n\n\n.pagination[_ngcontent-%COMP%] {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 16px 24px;\n    background: var(--mj-bg-page);\n    border-top: 1px solid var(--mj-border-default);\n}\n\n.page-info[_ngcontent-%COMP%] {\n    font-size: 13px;\n    color: var(--mj-text-secondary);\n}\n\n.page-buttons[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n}\n\n.page-btn[_ngcontent-%COMP%] {\n    min-width: 36px;\n    height: 36px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    font-size: 14px;\n    font-weight: 500;\n    color: var(--mj-text-secondary);\n    cursor: pointer;\n    transition: all 0.2s ease;\n}\n\n.page-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n    border-color: var(--mj-brand-primary);\n    color: var(--mj-brand-primary);\n}\n\n.page-btn.active[_ngcontent-%COMP%] {\n    background: var(--mj-brand-primary);\n    border-color: var(--mj-brand-primary);\n    color: var(--mj-text-inverse);\n}\n\n.page-btn[_ngcontent-%COMP%]:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n}\n\n.page-ellipsis[_ngcontent-%COMP%] {\n    padding: 0 8px;\n    color: var(--mj-text-muted);\n}\n\n\n\n@media (max-width: 1200px) {\n    .grid-header[_ngcontent-%COMP%], \n   .grid-row[_ngcontent-%COMP%] {\n        grid-template-columns: 2fr 1fr 90px 120px 100px;\n    }\n\n    .col-used[_ngcontent-%COMP%], \n   .col-created[_ngcontent-%COMP%] {\n        display: none;\n    }\n}\n\n@media (max-width: 1024px) {\n    .grid-header[_ngcontent-%COMP%], \n   .grid-row[_ngcontent-%COMP%] {\n        grid-template-columns: 2fr 90px 110px 100px;\n    }\n\n    .col-owner[_ngcontent-%COMP%] {\n        display: none;\n    }\n}\n\n@media (max-width: 768px) {\n    .list-header[_ngcontent-%COMP%] {\n        flex-direction: column;\n        gap: 16px;\n    }\n\n    .header-right[_ngcontent-%COMP%] {\n        width: 100%;\n        justify-content: space-between;\n    }\n\n    .search-box[_ngcontent-%COMP%]   input[_ngcontent-%COMP%] {\n        width: 180px;\n    }\n\n    .grid-header[_ngcontent-%COMP%], \n   .grid-row[_ngcontent-%COMP%] {\n        grid-template-columns: 2fr 90px 100px;\n    }\n\n    .col-expires[_ngcontent-%COMP%], \n   .col-scopes[_ngcontent-%COMP%] {\n        display: none;\n    }\n\n    .filter-tabs[_ngcontent-%COMP%] {\n        padding: 0 16px;\n    }\n}"] });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(APIKeyListComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'mj-api-key-list', template: "<div class=\"list-container\">\n  <!-- Header -->\n  <div class=\"list-header\">\n    <div class=\"header-left\">\n      <h3>API Keys</h3>\n      <span class=\"count-badge\">{{FilteredKeys.length}} of {{AllKeys.length}}</span>\n    </div>\n    <div class=\"header-right\">\n      <div class=\"search-box\">\n        <i class=\"fa-solid fa-search\"></i>\n        <input type=\"text\" [(ngModel)]=\"SearchText\"\n          (ngModelChange)=\"onSearch()\"\n          placeholder=\"Search keys...\" />\n        @if (SearchText) {\n          <button class=\"clear-search\" (click)=\"clearSearch()\">\n            <i class=\"fa-solid fa-times\"></i>\n          </button>\n        }\n      </div>\n      <button class=\"create-btn\" (click)=\"requestCreate()\">\n        <i class=\"fa-solid fa-plus\"></i>\n        Generate Key\n      </button>\n    </div>\n  </div>\n\n  <!-- Filter Tabs -->\n  <div class=\"filter-tabs\">\n    <button class=\"filter-tab\" [class.active]=\"Filter === 'all'\"\n      (click)=\"setFilter('all')\">\n      All\n      <span class=\"tab-count\">{{Stats.total}}</span>\n    </button>\n    <button class=\"filter-tab\" [class.active]=\"Filter === 'active'\"\n      (click)=\"setFilter('active')\">\n      <i class=\"fa-solid fa-check-circle status-active\"></i>\n      Active\n      <span class=\"tab-count\">{{Stats.active}}</span>\n    </button>\n    <button class=\"filter-tab\" [class.active]=\"Filter === 'expiring'\"\n      [class.has-warning]=\"Stats.expiring > 0\"\n      (click)=\"setFilter('expiring')\">\n      <i class=\"fa-solid fa-clock status-warning\"></i>\n      Expiring Soon\n      <span class=\"tab-count\">{{Stats.expiring}}</span>\n    </button>\n    <button class=\"filter-tab\" [class.active]=\"Filter === 'expired'\"\n      [class.has-danger]=\"Stats.expired > 0\"\n      (click)=\"setFilter('expired')\">\n      <i class=\"fa-solid fa-circle-exclamation status-danger\"></i>\n      Expired\n      <span class=\"tab-count\">{{Stats.expired}}</span>\n    </button>\n    <button class=\"filter-tab\" [class.active]=\"Filter === 'never-used'\"\n      (click)=\"setFilter('never-used')\">\n      <i class=\"fa-solid fa-question-circle status-info\"></i>\n      Never Used\n      <span class=\"tab-count\">{{Stats.neverUsed}}</span>\n    </button>\n    <button class=\"filter-tab\" [class.active]=\"Filter === 'revoked'\"\n      (click)=\"setFilter('revoked')\">\n      <i class=\"fa-solid fa-ban status-revoked\"></i>\n      Revoked\n      <span class=\"tab-count\">{{Stats.revoked}}</span>\n    </button>\n  </div>\n\n  <!-- Loading -->\n  @if (IsLoading) {\n    <mj-loading text=\"Loading API keys...\"></mj-loading>\n  }\n\n  <!-- Grid -->\n  @if (!IsLoading) {\n    <div class=\"key-grid\">\n      <!-- Header Row -->\n      <div class=\"grid-header\">\n        <div class=\"col-key sortable\" (click)=\"toggleSort('Label')\">\n          Key\n          <i [class]=\"getSortIcon('Label')\"></i>\n        </div>\n        <div class=\"col-owner sortable\" (click)=\"toggleSort('User')\">\n          Owner\n          <i [class]=\"getSortIcon('User')\"></i>\n        </div>\n        <div class=\"col-status sortable\" (click)=\"toggleSort('Status')\">\n          Status\n          <i [class]=\"getSortIcon('Status')\"></i>\n        </div>\n        <div class=\"col-scopes\">\n          Scopes\n        </div>\n        <div class=\"col-expires sortable\" (click)=\"toggleSort('ExpiresAt')\">\n          Expires\n          <i [class]=\"getSortIcon('ExpiresAt')\"></i>\n        </div>\n        <div class=\"col-used sortable\" (click)=\"toggleSort('LastUsedAt')\">\n          Last Used\n          <i [class]=\"getSortIcon('LastUsedAt')\"></i>\n        </div>\n        <div class=\"col-created sortable\" (click)=\"toggleSort('__mj_CreatedAt')\">\n          Created\n          <i [class]=\"getSortIcon('__mj_CreatedAt')\"></i>\n        </div>\n      </div>\n      <!-- Key Rows -->\n      @for (key of getPaginatedKeys(); track key) {\n        <div class=\"grid-row\"\n          (click)=\"selectKey(key)\">\n          <div class=\"col-key\">\n            <div class=\"key-icon\" [class.active]=\"key.Status === 'Active'\">\n              <i class=\"fa-solid fa-key\"></i>\n            </div>\n            <div class=\"key-details\">\n              <span class=\"key-label\">{{key.Label}}</span>\n              <code class=\"key-hash\">...{{key.Hash.slice(-12)}}</code>\n            </div>\n          </div>\n          <div class=\"col-owner\">\n            <span class=\"owner-name\">{{key.User}}</span>\n          </div>\n          <div class=\"col-status\">\n            <span class=\"status-badge\" [class.active]=\"key.Status === 'Active'\"\n              [class.revoked]=\"key.Status === 'Revoked'\">\n              {{key.Status}}\n            </span>\n          </div>\n          <div class=\"col-scopes\">\n            @if (getScopeInfo(key).count > 0) {\n              <div class=\"scopes-display\">\n                <div class=\"scope-badges\">\n                  @for (cat of getScopeInfo(key).categories; track cat; let i = $index) {\n                    @if (i < 3) {\n                      <span class=\"scope-badge\"\n                        [style.backgroundColor]=\"cat.color + '15'\"\n                        [style.color]=\"cat.color\"\n                        [title]=\"cat.category + ': ' + cat.count + ' scope(s)'\">\n                        <i [class]=\"cat.icon\"></i>\n                        <span class=\"badge-count\">{{cat.count}}</span>\n                      </span>\n                    }\n                  }\n                  @if (getScopeInfo(key).categories.length > 3) {\n                    <span class=\"scope-more\">\n                      +{{getScopeInfo(key).categories.length - 3}}\n                    </span>\n                  }\n                </div>\n                <span class=\"scopes-total\">\n                  {{getScopeInfo(key).count}} total\n                </span>\n              </div>\n            }\n            @if (getScopeInfo(key).count === 0) {\n              <span class=\"no-scopes\">\n                <i class=\"fa-solid fa-shield-xmark\"></i>\n                None\n              </span>\n            }\n          </div>\n          <div class=\"col-expires\">\n            <span class=\"expires-value\" [ngClass]=\"getExpirationClass(key)\">\n              {{formatExpiration(key.ExpiresAt)}}\n            </span>\n          </div>\n          <div class=\"col-used\">\n            <span class=\"used-value\" [class.never]=\"!key.LastUsedAt\">\n              {{formatDate(key.LastUsedAt)}}\n            </span>\n          </div>\n          <div class=\"col-created\">\n            <span class=\"created-value\">{{formatDate(key.__mj_CreatedAt)}}</span>\n          </div>\n        </div>\n      }\n      <!-- Empty State -->\n      @if (FilteredKeys.length === 0) {\n        <mj-empty-state\n          [Variant]=\"(SearchText || Filter !== 'all') ? 'no-results' : 'empty'\"\n          Icon=\"fa-solid fa-key\"\n          [Title]=\"EmptyStateTitle\"\n          [ActionText]=\"(!SearchText && Filter === 'all') ? 'Generate Your First Key' : ''\"\n          ActionIcon=\"fa-solid fa-plus\"\n          (Action)=\"requestCreate()\" />\n      }\n    </div>\n  }\n\n  <!-- Pagination -->\n  @if (!IsLoading && FilteredKeys.length > PageSize) {\n    <div class=\"pagination\">\n      <div class=\"page-info\">\n        Showing {{(CurrentPage - 1) * PageSize + 1}} - {{Math.min(CurrentPage * PageSize, FilteredKeys.length)}}\n        of {{FilteredKeys.length}}\n      </div>\n      <div class=\"page-buttons\">\n        <button class=\"page-btn\" [disabled]=\"CurrentPage === 1\"\n          (click)=\"goToPage(CurrentPage - 1)\">\n          <i class=\"fa-solid fa-chevron-left\"></i>\n        </button>\n        @for (page of getPageNumbers(); track page) {\n          @if (page > 0) {\n            <button class=\"page-btn\"\n              [class.active]=\"page === CurrentPage\"\n              (click)=\"goToPage(page)\">\n              {{page}}\n            </button>\n          }\n          @if (page === -1) {\n            <span class=\"page-ellipsis\">...</span>\n          }\n        }\n        <button class=\"page-btn\" [disabled]=\"CurrentPage === getTotalPages()\"\n          (click)=\"goToPage(CurrentPage + 1)\">\n          <i class=\"fa-solid fa-chevron-right\"></i>\n        </button>\n      </div>\n    </div>\n  }\n</div>\n", styles: [".list-container {\n    display: flex;\n    flex-direction: column;\n    height: 100%;\n    background: var(--mj-bg-surface);\n    border-radius: 12px;\n    overflow: hidden;\n    box-shadow: var(--mj-shadow-md);\n}\n\n/* Header */\n.list-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 20px 24px;\n    background: linear-gradient(135deg, var(--mj-color-brand-100) 0%, var(--mj-color-brand-200) 100%);\n    border-bottom: 1px solid var(--mj-color-accent-300);\n}\n\n.header-left {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n}\n\n.header-left h3 {\n    margin: 0;\n    font-size: 20px;\n    font-weight: 700;\n    color: var(--mj-color-brand-800);\n}\n\n.count-badge {\n    padding: 4px 12px;\n    background: rgba(255, 255, 255, 0.7);\n    border-radius: 20px;\n    font-size: 13px;\n    font-weight: 500;\n    color: var(--mj-color-brand-800);\n}\n\n.header-right {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n}\n\n/* Search Box */\n.search-box {\n    position: relative;\n    display: flex;\n    align-items: center;\n}\n\n.search-box i {\n    position: absolute;\n    left: 12px;\n    color: var(--mj-text-muted);\n    font-size: 14px;\n}\n\n.search-box input {\n    width: 260px;\n    padding: 10px 36px;\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 8px;\n    font-size: 14px;\n    transition: all 0.2s ease;\n}\n\n.search-box input:focus {\n    outline: none;\n    border-color: var(--mj-brand-primary);\n    box-shadow: var(--mj-focus-ring);\n}\n\n.clear-search {\n    position: absolute;\n    right: 8px;\n    width: 24px;\n    height: 24px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    background: var(--mj-border-default);\n    border: none;\n    border-radius: 50%;\n    cursor: pointer;\n    transition: all 0.2s ease;\n}\n\n.clear-search:hover {\n    background: var(--mj-color-neutral-300);\n}\n\n.clear-search i {\n    position: static;\n    font-size: 10px;\n    color: var(--mj-text-secondary);\n}\n\n/* Create Button */\n.create-btn {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n    padding: 10px 20px;\n    background: var(--mj-brand-primary);\n    border: none;\n    border-radius: 8px;\n    font-size: 14px;\n    font-weight: 600;\n    color: var(--mj-text-inverse);\n    cursor: pointer;\n    transition: all 0.2s ease;\n}\n\n.create-btn:hover {\n    transform: translateY(-1px);\n    box-shadow: var(--mj-shadow-brand-md);\n}\n\n/* Filter Tabs */\n.filter-tabs {\n    display: flex;\n    gap: 4px;\n    padding: 0 24px;\n    background: var(--mj-bg-page);\n    border-bottom: 1px solid var(--mj-border-default);\n    overflow-x: auto;\n}\n\n.filter-tab {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n    padding: 14px 16px;\n    background: transparent;\n    border: none;\n    border-bottom: 2px solid transparent;\n    font-size: 13px;\n    font-weight: 500;\n    color: var(--mj-text-secondary);\n    cursor: pointer;\n    white-space: nowrap;\n    transition: all 0.2s ease;\n}\n\n.filter-tab:hover {\n    color: var(--mj-text-secondary);\n    background: var(--mj-bg-surface-sunken);\n}\n\n.filter-tab.active {\n    color: var(--mj-brand-primary);\n    border-bottom-color: var(--mj-brand-primary);\n}\n\n.filter-tab.has-warning .tab-count {\n    background: var(--mj-color-brand-100);\n    color: var(--mj-brand-primary-hover);\n}\n\n.filter-tab.has-danger .tab-count {\n    background: var(--mj-color-error-100);\n    color: var(--mj-color-error-600);\n}\n\n.tab-count {\n    padding: 2px 8px;\n    background: var(--mj-border-default);\n    border-radius: 10px;\n    font-size: 11px;\n    font-weight: 600;\n}\n\n.status-active { color: var(--mj-status-success); }\n.status-warning { color: var(--mj-color-warning-500); }\n.status-danger { color: var(--mj-status-error); }\n.status-info { color: var(--mj-text-secondary); }\n.status-revoked { color: var(--mj-text-secondary); }\n\n/* Key Grid */\n.key-grid {\n    flex: 1;\n    overflow-y: auto;\n}\n\n.grid-header {\n    display: grid;\n    grid-template-columns: 2fr 1fr 90px 160px 100px 110px 100px;\n    gap: 12px;\n    padding: 14px 24px;\n    background: var(--mj-bg-surface-sunken);\n    border-bottom: 1px solid var(--mj-border-default);\n    font-size: 11px;\n    font-weight: 600;\n    color: var(--mj-text-secondary);\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    position: sticky;\n    top: 0;\n}\n\n.sortable {\n    cursor: pointer;\n    display: flex;\n    align-items: center;\n    gap: 6px;\n    transition: color 0.2s ease;\n}\n\n.sortable:hover {\n    color: var(--mj-text-secondary);\n}\n\n.sortable i {\n    font-size: 10px;\n    opacity: 0.5;\n}\n\n/* Grid Rows */\n.grid-row {\n    display: grid;\n    grid-template-columns: 2fr 1fr 90px 160px 100px 110px 100px;\n    gap: 12px;\n    padding: 16px 24px;\n    border-bottom: 1px solid var(--mj-bg-surface-sunken);\n    cursor: pointer;\n    transition: background 0.2s ease;\n    align-items: center;\n}\n\n.grid-row:hover {\n    background: var(--mj-color-brand-50);\n}\n\n.grid-row:last-child {\n    border-bottom: none;\n}\n\n/* Key Column */\n.col-key {\n    display: flex;\n    align-items: center;\n    gap: 14px;\n    min-width: 0;\n}\n\n.key-icon {\n    width: 40px;\n    height: 40px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    background: linear-gradient(135deg, var(--mj-text-secondary) 0%, var(--mj-color-neutral-600) 100%);\n    border-radius: 8px;\n    flex-shrink: 0;\n}\n\n.key-icon.active {\n    background: var(--mj-brand-primary);\n}\n\n.key-icon i {\n    font-size: 16px;\n    color: var(--mj-text-inverse);\n}\n\n.key-details {\n    display: flex;\n    flex-direction: column;\n    gap: 4px;\n    min-width: 0;\n}\n\n.key-label {\n    font-weight: 600;\n    font-size: 14px;\n    color: var(--mj-text-primary);\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n}\n\n.key-hash {\n    font-family: 'Fira Code', 'Consolas', monospace;\n    font-size: 11px;\n    color: var(--mj-text-secondary);\n    background: var(--mj-bg-surface-sunken);\n    padding: 2px 6px;\n    border-radius: 4px;\n}\n\n/* Owner Column */\n.owner-name {\n    font-size: 14px;\n    color: var(--mj-text-secondary);\n}\n\n/* Status Column */\n.status-badge {\n    display: inline-block;\n    padding: 4px 10px;\n    border-radius: 12px;\n    font-size: 12px;\n    font-weight: 600;\n    text-transform: capitalize;\n}\n\n.status-badge.active {\n    background: var(--mj-color-success-100);\n    color: var(--mj-color-success-600);\n}\n\n.status-badge.revoked {\n    background: var(--mj-bg-surface-sunken);\n    color: var(--mj-text-secondary);\n}\n\n/* Scopes Column */\n.col-scopes {\n    display: flex;\n    flex-direction: column;\n    gap: 4px;\n    min-width: 0;\n}\n\n.scopes-display {\n    display: flex;\n    flex-direction: column;\n    gap: 4px;\n}\n\n.scope-badges {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n    flex-wrap: wrap;\n}\n\n.scope-badge {\n    display: inline-flex;\n    align-items: center;\n    gap: 4px;\n    padding: 3px 8px;\n    border-radius: 12px;\n    font-size: 11px;\n    font-weight: 600;\n    cursor: default;\n    transition: transform 0.15s ease;\n}\n\n.scope-badge:hover {\n    transform: scale(1.05);\n}\n\n.scope-badge i {\n    font-size: 10px;\n}\n\n.badge-count {\n    font-weight: 700;\n}\n\n.scope-more {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    padding: 3px 6px;\n    background: var(--mj-bg-surface-sunken);\n    border-radius: 12px;\n    font-size: 10px;\n    font-weight: 600;\n    color: var(--mj-text-secondary);\n}\n\n.scopes-total {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n.no-scopes {\n    display: inline-flex;\n    align-items: center;\n    gap: 4px;\n    font-size: 12px;\n    color: var(--mj-color-neutral-300);\n}\n\n.no-scopes i {\n    font-size: 11px;\n}\n\n/* Expires Column */\n.expires-value {\n    font-size: 13px;\n}\n\n.expires-value.never {\n    color: var(--mj-text-secondary);\n}\n\n.expires-value.ok {\n    color: var(--mj-color-success-600);\n}\n\n.expires-value.warning {\n    color: var(--mj-brand-primary-hover);\n    font-weight: 500;\n}\n\n.expires-value.critical {\n    color: var(--mj-color-error-600);\n    font-weight: 600;\n}\n\n.expires-value.expired {\n    color: var(--mj-color-error-600);\n    font-weight: 600;\n}\n\n/* Used Column */\n.used-value {\n    font-size: 13px;\n    color: var(--mj-text-secondary);\n}\n\n.used-value.never {\n    color: var(--mj-text-muted);\n    font-style: italic;\n}\n\n/* Created Column */\n.created-value {\n    font-size: 13px;\n    color: var(--mj-text-secondary);\n}\n\n/* Pagination */\n.pagination {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 16px 24px;\n    background: var(--mj-bg-page);\n    border-top: 1px solid var(--mj-border-default);\n}\n\n.page-info {\n    font-size: 13px;\n    color: var(--mj-text-secondary);\n}\n\n.page-buttons {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n}\n\n.page-btn {\n    min-width: 36px;\n    height: 36px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    font-size: 14px;\n    font-weight: 500;\n    color: var(--mj-text-secondary);\n    cursor: pointer;\n    transition: all 0.2s ease;\n}\n\n.page-btn:hover:not(:disabled) {\n    border-color: var(--mj-brand-primary);\n    color: var(--mj-brand-primary);\n}\n\n.page-btn.active {\n    background: var(--mj-brand-primary);\n    border-color: var(--mj-brand-primary);\n    color: var(--mj-text-inverse);\n}\n\n.page-btn:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n}\n\n.page-ellipsis {\n    padding: 0 8px;\n    color: var(--mj-text-muted);\n}\n\n/* Responsive */\n@media (max-width: 1200px) {\n    .grid-header,\n    .grid-row {\n        grid-template-columns: 2fr 1fr 90px 120px 100px;\n    }\n\n    .col-used,\n    .col-created {\n        display: none;\n    }\n}\n\n@media (max-width: 1024px) {\n    .grid-header,\n    .grid-row {\n        grid-template-columns: 2fr 90px 110px 100px;\n    }\n\n    .col-owner {\n        display: none;\n    }\n}\n\n@media (max-width: 768px) {\n    .list-header {\n        flex-direction: column;\n        gap: 16px;\n    }\n\n    .header-right {\n        width: 100%;\n        justify-content: space-between;\n    }\n\n    .search-box input {\n        width: 180px;\n    }\n\n    .grid-header,\n    .grid-row {\n        grid-template-columns: 2fr 90px 100px;\n    }\n\n    .col-expires,\n    .col-scopes {\n        display: none;\n    }\n\n    .filter-tabs {\n        padding: 0 16px;\n    }\n}\n"] }]
    }], null, { Filter: [{
            type: Input
        }], KeySelected: [{
            type: Output
        }], CreateRequested: [{
            type: Output
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(APIKeyListComponent, { className: "APIKeyListComponent", filePath: "src/APIKeys/api-key-list.component.ts", lineNumber: 33 }); })();
//# sourceMappingURL=api-key-list.component.js.map