import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
import { CompositeKey } from '@memberjunction/core';
import { UUIDsEqual } from '@memberjunction/global';
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@memberjunction/ng-trees";
const _c0 = ["entityTree"];
const _forTrack0 = ($index, $item) => $item.entityName;
const _forTrack1 = ($index, $item) => $item.entityName + "|" + $item.compositeKeyString;
function NavigationPanelComponent_Conditional_3_Conditional_6_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 10);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1("(", ctx_r1.favoriteRecords.length + ctx_r1.favoriteEntities.length, ")");
} }
function NavigationPanelComponent_Conditional_3_Conditional_8_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 18)(1, "span");
    i0.ɵɵtext(2, "No favorites yet");
    i0.ɵɵelementEnd()();
} }
function NavigationPanelComponent_Conditional_3_Conditional_8_Conditional_2_For_3_Template(rf, ctx) { if (rf & 1) {
    const _r3 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 22);
    i0.ɵɵlistener("click", function NavigationPanelComponent_Conditional_3_Conditional_8_Conditional_2_For_3_Template_div_click_0_listener() { const favorite_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.onFavoriteClick(favorite_r4)); });
    i0.ɵɵelement(1, "i");
    i0.ɵɵelementStart(2, "span", 23);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const favorite_r4 = ctx.$implicit;
    const ctx_r1 = i0.ɵɵnextContext(4);
    i0.ɵɵproperty("title", favorite_r4.entityName ? favorite_r4.entityName + " - " + favorite_r4.displayName : favorite_r4.displayName);
    i0.ɵɵadvance();
    i0.ɵɵclassMap(ctx_r1.getFavoriteIcon(favorite_r4));
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(favorite_r4.displayName);
} }
function NavigationPanelComponent_Conditional_3_Conditional_8_Conditional_2_For_5_Template(rf, ctx) { if (rf & 1) {
    const _r5 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 22);
    i0.ɵɵlistener("click", function NavigationPanelComponent_Conditional_3_Conditional_8_Conditional_2_For_5_Template_div_click_0_listener() { const favorite_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.onFavoriteClick(favorite_r6)); });
    i0.ɵɵelement(1, "i");
    i0.ɵɵelementStart(2, "span", 23);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const favorite_r6 = ctx.$implicit;
    const ctx_r1 = i0.ɵɵnextContext(4);
    i0.ɵɵproperty("title", favorite_r6.entityName ? favorite_r6.entityName + " - " + favorite_r6.displayName : favorite_r6.displayName);
    i0.ɵɵadvance();
    i0.ɵɵclassMap(ctx_r1.getFavoriteIcon(favorite_r6));
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(favorite_r6.displayName);
} }
function NavigationPanelComponent_Conditional_3_Conditional_8_Conditional_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 19)(1, "div", 20);
    i0.ɵɵrepeaterCreate(2, NavigationPanelComponent_Conditional_3_Conditional_8_Conditional_2_For_3_Template, 4, 4, "div", 21, _forTrack0);
    i0.ɵɵrepeaterCreate(4, NavigationPanelComponent_Conditional_3_Conditional_8_Conditional_2_For_5_Template, 4, 4, "div", 21, _forTrack1);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(3);
    i0.ɵɵadvance(2);
    i0.ɵɵrepeater(ctx_r1.favoriteEntities);
    i0.ɵɵadvance(2);
    i0.ɵɵrepeater(ctx_r1.favoriteRecords);
} }
function NavigationPanelComponent_Conditional_3_Conditional_8_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 12);
    i0.ɵɵconditionalCreate(1, NavigationPanelComponent_Conditional_3_Conditional_8_Conditional_1_Template, 3, 0, "div", 18)(2, NavigationPanelComponent_Conditional_3_Conditional_8_Conditional_2_Template, 6, 0, "div", 19);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r1.favoriteRecords.length + ctx_r1.favoriteEntities.length === 0 ? 1 : 2);
} }
function NavigationPanelComponent_Conditional_3_Conditional_14_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 10);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1("(", ctx_r1.filteredRecentItems.length, ")");
} }
function NavigationPanelComponent_Conditional_3_Conditional_16_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 18)(1, "span");
    i0.ɵɵtext(2, "No recent items");
    i0.ɵɵelementEnd()();
} }
function NavigationPanelComponent_Conditional_3_Conditional_16_Conditional_2_For_3_Template(rf, ctx) { if (rf & 1) {
    const _r7 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 22);
    i0.ɵɵlistener("click", function NavigationPanelComponent_Conditional_3_Conditional_16_Conditional_2_For_3_Template_div_click_0_listener() { const item_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.onRecentClick(item_r8)); });
    i0.ɵɵelement(1, "i");
    i0.ɵɵelementStart(2, "div", 24)(3, "span", 23);
    i0.ɵɵtext(4);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "span", 25);
    i0.ɵɵtext(6);
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const item_r8 = ctx.$implicit;
    const ctx_r1 = i0.ɵɵnextContext(4);
    i0.ɵɵproperty("title", item_r8.entityName + " - " + item_r8.displayName);
    i0.ɵɵadvance();
    i0.ɵɵclassMap(ctx_r1.getRecentItemIcon(item_r8));
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(item_r8.displayName);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(ctx_r1.formatTimestamp(item_r8.timestamp));
} }
function NavigationPanelComponent_Conditional_3_Conditional_16_Conditional_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 19)(1, "div", 20);
    i0.ɵɵrepeaterCreate(2, NavigationPanelComponent_Conditional_3_Conditional_16_Conditional_2_For_3_Template, 7, 5, "div", 21, _forTrack1);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(3);
    i0.ɵɵadvance(2);
    i0.ɵɵrepeater(ctx_r1.filteredRecentItems);
} }
function NavigationPanelComponent_Conditional_3_Conditional_16_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 12);
    i0.ɵɵconditionalCreate(1, NavigationPanelComponent_Conditional_3_Conditional_16_Conditional_1_Template, 3, 0, "div", 18)(2, NavigationPanelComponent_Conditional_3_Conditional_16_Conditional_2_Template, 4, 0, "div", 19);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r1.filteredRecentItems.length === 0 ? 1 : 2);
} }
function NavigationPanelComponent_Conditional_3_Conditional_25_Conditional_4_Template(rf, ctx) { if (rf & 1) {
    const _r10 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "button", 31);
    i0.ɵɵlistener("click", function NavigationPanelComponent_Conditional_3_Conditional_25_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.clearEntitySearch()); });
    i0.ɵɵelement(1, "i", 32);
    i0.ɵɵelementEnd();
} }
function NavigationPanelComponent_Conditional_3_Conditional_25_Template(rf, ctx) { if (rf & 1) {
    const _r9 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 17)(1, "div", 26);
    i0.ɵɵelement(2, "i", 27);
    i0.ɵɵelementStart(3, "input", 28);
    i0.ɵɵtwoWayListener("ngModelChange", function NavigationPanelComponent_Conditional_3_Conditional_25_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.entitySearchTerm, $event) || (ctx_r1.entitySearchTerm = $event); return i0.ɵɵresetView($event); });
    i0.ɵɵlistener("ngModelChange", function NavigationPanelComponent_Conditional_3_Conditional_25_Template_input_ngModelChange_3_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onEntitySearchChanged()); });
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(4, NavigationPanelComponent_Conditional_3_Conditional_25_Conditional_4_Template, 2, 0, "button", 29);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "mj-tree", 30, 0);
    i0.ɵɵlistener("SelectionChange", function NavigationPanelComponent_Conditional_3_Conditional_25_Template_mj_tree_SelectionChange_5_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onTreeEntitySelected($event)); });
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance(3);
    i0.ɵɵtwoWayProperty("ngModel", ctx_r1.entitySearchTerm);
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r1.entitySearchTerm ? 4 : -1);
    i0.ɵɵadvance();
    i0.ɵɵproperty("BranchConfig", ctx_r1.treeBranchConfig)("LeafConfig", ctx_r1.treeLeafConfig)("SelectionMode", "single")("SelectableTypes", "leaf")("SelectedIDs", ctx_r1.selectedEntityIds)("ShowIcons", true)("ShowExpandCollapseAll", false)("AnimateExpandCollapse", true)("EmptyMessage", ctx_r1.entitySearchTerm ? "No matches for: " + ctx_r1.entitySearchTerm : "No entities available")("EmptyIcon", "fa-solid fa-database");
} }
function NavigationPanelComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
    const _r1 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 4)(1, "div", 6)(2, "div", 7);
    i0.ɵɵlistener("click", function NavigationPanelComponent_Conditional_3_Template_div_click_2_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSectionToggle("favorites")); });
    i0.ɵɵelement(3, "i", 8);
    i0.ɵɵelementStart(4, "span", 9);
    i0.ɵɵtext(5, "Favorites");
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(6, NavigationPanelComponent_Conditional_3_Conditional_6_Template, 2, 1, "span", 10);
    i0.ɵɵelement(7, "i", 11);
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(8, NavigationPanelComponent_Conditional_3_Conditional_8_Template, 3, 1, "div", 12);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(9, "div", 13)(10, "div", 7);
    i0.ɵɵlistener("click", function NavigationPanelComponent_Conditional_3_Template_div_click_10_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSectionToggle("recent")); });
    i0.ɵɵelement(11, "i", 14);
    i0.ɵɵelementStart(12, "span", 9);
    i0.ɵɵtext(13, "Recent");
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(14, NavigationPanelComponent_Conditional_3_Conditional_14_Template, 2, 1, "span", 10);
    i0.ɵɵelement(15, "i", 11);
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(16, NavigationPanelComponent_Conditional_3_Conditional_16_Template, 3, 1, "div", 12);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(17, "div", 15)(18, "div", 7);
    i0.ɵɵlistener("click", function NavigationPanelComponent_Conditional_3_Template_div_click_18_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSectionToggle("entities")); });
    i0.ɵɵelement(19, "i", 16);
    i0.ɵɵelementStart(20, "span", 9);
    i0.ɵɵtext(21, "Entities");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(22, "span", 10);
    i0.ɵɵtext(23);
    i0.ɵɵelementEnd();
    i0.ɵɵelement(24, "i", 11);
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(25, NavigationPanelComponent_Conditional_3_Conditional_25_Template, 7, 12, "div", 17);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext();
    i0.ɵɵadvance(6);
    i0.ɵɵconditional(ctx_r1.favoriteRecords.length + ctx_r1.favoriteEntities.length > 0 ? 6 : -1);
    i0.ɵɵadvance();
    i0.ɵɵclassProp("fa-chevron-down", ctx_r1.favoritesSectionExpanded)("fa-chevron-right", !ctx_r1.favoritesSectionExpanded);
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r1.favoritesSectionExpanded ? 8 : -1);
    i0.ɵɵadvance(6);
    i0.ɵɵconditional(ctx_r1.filteredRecentItems.length > 0 ? 14 : -1);
    i0.ɵɵadvance();
    i0.ɵɵclassProp("fa-chevron-down", ctx_r1.recentSectionExpanded)("fa-chevron-right", !ctx_r1.recentSectionExpanded);
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r1.recentSectionExpanded ? 16 : -1);
    i0.ɵɵadvance(7);
    i0.ɵɵtextInterpolate1("(", ctx_r1.entities.length, ")");
    i0.ɵɵadvance();
    i0.ɵɵclassProp("fa-chevron-down", ctx_r1.entitiesSectionExpanded)("fa-chevron-right", !ctx_r1.entitiesSectionExpanded);
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r1.entitiesSectionExpanded ? 25 : -1);
} }
function NavigationPanelComponent_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 35);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(ctx_r1.favoriteRecords.length + ctx_r1.favoriteEntities.length);
} }
function NavigationPanelComponent_Conditional_4_Conditional_6_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 35);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(ctx_r1.filteredRecentItems.length);
} }
function NavigationPanelComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
    const _r11 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 5)(1, "button", 33);
    i0.ɵɵlistener("click", function NavigationPanelComponent_Conditional_4_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onCollapsedIconClick("favorites")); });
    i0.ɵɵelement(2, "i", 34);
    i0.ɵɵconditionalCreate(3, NavigationPanelComponent_Conditional_4_Conditional_3_Template, 2, 1, "span", 35);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "button", 36);
    i0.ɵɵlistener("click", function NavigationPanelComponent_Conditional_4_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onCollapsedIconClick("recent")); });
    i0.ɵɵelement(5, "i", 37);
    i0.ɵɵconditionalCreate(6, NavigationPanelComponent_Conditional_4_Conditional_6_Template, 2, 1, "span", 35);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(7, "button", 38);
    i0.ɵɵlistener("click", function NavigationPanelComponent_Conditional_4_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onCollapsedIconClick("entities")); });
    i0.ɵɵelement(8, "i", 39);
    i0.ɵɵelementStart(9, "span", 35);
    i0.ɵɵtext(10);
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext();
    i0.ɵɵadvance(3);
    i0.ɵɵconditional(ctx_r1.favoriteRecords.length + ctx_r1.favoriteEntities.length > 0 ? 3 : -1);
    i0.ɵɵadvance(3);
    i0.ɵɵconditional(ctx_r1.filteredRecentItems.length > 0 ? 6 : -1);
    i0.ɵɵadvance(4);
    i0.ɵɵtextInterpolate(ctx_r1.entities.length);
} }
export class NavigationPanelComponent extends BaseAngularComponent {
    cdr;
    constructor(cdr) {
        super();
        this.cdr = cdr;
    }
    entities = [];
    selectedEntityName = null;
    favorites = [];
    recentItems = [];
    collapsed = false;
    /**
     * Optional set of allowed entity names for filtering favorites/recents.
     * If provided, only items matching these entities will be shown.
     */
    allowedEntityNames = null;
    /** Application-based entity groups from the parent dashboard */
    appEntityGroups = [];
    /** Optional application ID filter for the tree */
    applicationIdFilter = null;
    // Section expansion states
    favoritesSectionExpanded = true;
    recentSectionExpanded = true;
    entitiesSectionExpanded = true;
    viewsSectionExpanded = true;
    entitySelected = new EventEmitter();
    toggleCollapse = new EventEmitter();
    sectionToggled = new EventEmitter();
    openRecord = new EventEmitter();
    /** Emitted when a record should be selected within Data Explorer (navigate to entity + select record) */
    selectRecord = new EventEmitter();
    /** Emitted when a collapsed icon is clicked - expands panel and focuses section */
    expandAndFocus = new EventEmitter();
    /** Emitted when a nav panel app group is toggled */
    appGroupToggled = new EventEmitter();
    get metadata() { return this.ProviderToUse; }
    // Tree configuration for entity list
    treeBranchConfig = {
        EntityName: 'MJ: Applications',
        DisplayField: 'Name',
        IDField: 'ID',
        IconField: 'Icon',
        OrderBy: 'Name'
    };
    treeLeafConfig = {
        EntityName: 'MJ: Entities',
        ParentField: '', // Using JunctionConfig for M2M relationship
        DisplayField: 'Name',
        IDField: 'ID',
        IconField: 'Icon',
        JunctionConfig: {
            EntityName: 'MJ: Application Entities',
            BranchForeignKey: 'ApplicationID',
            LeafForeignKey: 'EntityID'
        },
        OrderBy: 'Name'
    };
    entityTree;
    /** Selected entity ID for tree highlighting */
    selectedEntityIds = [];
    /** Search term for filtering the entity tree */
    entitySearchTerm = '';
    ngOnChanges(changes) {
        if (changes['selectedEntityName']) {
            this.updateSelectedEntityKey();
        }
        if (changes['applicationIdFilter']) {
            this.updateTreeBranchFilter();
        }
        if (changes['recentItems']) {
            this.timestampLabelCache.clear();
        }
    }
    ngOnInit() {
        this.timestampRefreshHandle = setInterval(() => {
            if (this.timestampLabelCache.size === 0)
                return;
            this.timestampLabelCache.clear();
            this.cdr.markForCheck();
        }, 30000);
    }
    ngOnDestroy() {
        if (this.timestampRefreshHandle !== undefined) {
            clearInterval(this.timestampRefreshHandle);
            this.timestampRefreshHandle = undefined;
        }
    }
    /**
     * Update the selected entity IDs for tree highlighting when selected entity changes
     */
    updateSelectedEntityKey() {
        if (this.selectedEntityName) {
            const entity = this.metadata.Entities.find(e => e.Name === this.selectedEntityName);
            if (entity) {
                this.selectedEntityIds = [entity.ID];
                return;
            }
        }
        this.selectedEntityIds = [];
    }
    /**
     * Update the tree's branch filter when application filter changes
     */
    updateTreeBranchFilter() {
        if (this.applicationIdFilter) {
            this.treeBranchConfig = {
                ...this.treeBranchConfig,
                ExtraFilter: `ID='${this.applicationIdFilter}'`
            };
        }
        else {
            this.treeBranchConfig = {
                ...this.treeBranchConfig,
                ExtraFilter: undefined
            };
        }
    }
    /**
     * Filter the entity tree when search term changes
     */
    onEntitySearchChanged() {
        if (this.entityTree) {
            this.entityTree.FilterNodes(this.entitySearchTerm, {
                searchBranches: true,
                searchLeaves: true,
                caseSensitive: false
            });
        }
    }
    /**
     * Clear the entity search
     */
    clearEntitySearch() {
        this.entitySearchTerm = '';
        this.onEntitySearchChanged();
    }
    /**
     * Handle tree selection change - map TreeNode to EntityInfo and emit
     */
    onTreeEntitySelected(nodes) {
        if (!nodes || nodes.length === 0)
            return;
        const node = nodes[0];
        if (node.Type !== 'leaf')
            return;
        // Find the EntityInfo by ID from the node
        const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, node.ID));
        if (entity) {
            this.entitySelected.emit(entity);
        }
    }
    /**
     * Get recent items filtered by allowed entities (if filter is active)
     */
    get filteredRecentItems() {
        if (!this.allowedEntityNames) {
            return this.recentItems;
        }
        return this.recentItems.filter(r => this.allowedEntityNames.has(r.entityName));
    }
    /**
     * Get favorites filtered to records only (respecting entity filter)
     */
    get favoriteRecords() {
        const records = this.favorites.filter(f => f.type === 'record');
        if (!this.allowedEntityNames) {
            return records;
        }
        return records.filter(f => f.entityName && this.allowedEntityNames.has(f.entityName));
    }
    /**
     * Get favorites filtered to entities only (respecting entity filter)
     */
    get favoriteEntities() {
        const entities = this.favorites.filter(f => f.type === 'entity');
        if (!this.allowedEntityNames) {
            return entities;
        }
        return entities.filter(f => f.entityName && this.allowedEntityNames.has(f.entityName));
    }
    /**
     * Handle entity click
     */
    onEntityClick(entity) {
        this.entitySelected.emit(entity);
    }
    /**
     * Handle favorite click - navigates to entity and selects record within Data Explorer
     */
    onFavoriteClick(favorite) {
        if (favorite.type === 'entity' && favorite.entityName) {
            const entity = this.entities.find(e => e.Name === favorite.entityName);
            if (entity) {
                this.entitySelected.emit(entity);
            }
        }
        else if (favorite.type === 'record' && favorite.entityName && favorite.compositeKeyString) {
            // Extract record ID from the composite key string
            // Format is "FieldName|Value" or "FieldName|Value||FieldName2|Value2"
            const compositeKey = new CompositeKey();
            compositeKey.LoadFromConcatenatedString(favorite.compositeKeyString);
            const recordId = compositeKey.KeyValuePairs[0]?.Value?.toString() || '';
            // Navigate to entity and select record within Data Explorer (not full tab)
            this.selectRecord.emit({
                entityName: favorite.entityName,
                recordId
            });
        }
    }
    /**
     * Handle recent item click - navigates to entity and selects record within Data Explorer
     */
    onRecentClick(item) {
        // Extract record ID from the composite key string
        const compositeKey = new CompositeKey();
        compositeKey.LoadFromConcatenatedString(item.compositeKeyString);
        const recordId = compositeKey.KeyValuePairs[0]?.Value?.toString() || '';
        // Navigate to entity and select record within Data Explorer (not full tab)
        this.selectRecord.emit({
            entityName: item.entityName,
            recordId
        });
    }
    /**
     * Handle section header click
     */
    onSectionToggle(section) {
        this.sectionToggled.emit(section);
    }
    /**
     * Handle collapse toggle
     */
    onToggleCollapse() {
        this.toggleCollapse.emit();
    }
    /**
     * Handle collapsed icon click - expands panel and focuses section
     */
    onCollapsedIconClick(section) {
        this.expandAndFocus.emit(section);
    }
    /**
     * Check if entity is selected
     */
    isEntitySelected(entity) {
        return entity.Name === this.selectedEntityName;
    }
    /**
     * Get icon for entity
     */
    getEntityIcon(entity) {
        const icon = entity.Icon;
        if (!icon) {
            return 'fa-solid fa-table';
        }
        // If icon already has fa- prefix, use it as-is
        if (icon.startsWith('fa-') || icon.startsWith('fa ')) {
            // Ensure it has a style prefix (fa-solid, fa-regular, etc.)
            if (icon.startsWith('fa-solid') || icon.startsWith('fa-regular') ||
                icon.startsWith('fa-light') || icon.startsWith('fa-brands') ||
                icon.startsWith('fa ')) {
                return icon;
            }
            // It's just "fa-something", add fa-solid prefix
            return `fa-solid ${icon}`;
        }
        // Check if it's just an icon name like "table" or "users"
        return `fa-solid fa-${icon}`;
    }
    /**
     * Cache of formatted relative-time labels keyed by timestamp epoch ms.
     * Stable within a change-detection cycle (avoids NG0100 from `now`-dependent
     * values shifting between dirty-check and verify passes). Cleared on a coarse
     * interval so the displayed label still updates over time.
     */
    timestampLabelCache = new Map();
    timestampRefreshHandle;
    /**
     * Format recent item timestamp. Cached per-timestamp so the same value is
     * returned across change-detection passes within a single tick — recomputed
     * on a 30-second interval (see `ngOnInit`).
     */
    formatTimestamp(timestamp) {
        const epoch = new Date(timestamp).getTime();
        const cached = this.timestampLabelCache.get(epoch);
        if (cached !== undefined) {
            return cached;
        }
        const label = this.computeRelativeLabel(epoch);
        this.timestampLabelCache.set(epoch, label);
        return label;
    }
    computeRelativeLabel(epoch) {
        const diffMs = Date.now() - epoch;
        const diffMins = Math.floor(diffMs / 60000);
        if (diffMins < 1)
            return 'Just now';
        if (diffMins < 60)
            return `${diffMins}m ago`;
        const diffHours = Math.floor(diffMins / 60);
        if (diffHours < 24)
            return `${diffHours}h ago`;
        const diffDays = Math.floor(diffHours / 24);
        if (diffDays < 7)
            return `${diffDays}d ago`;
        return new Date(epoch).toLocaleDateString();
    }
    /**
     * Get icon for a recent item based on its entity
     */
    getRecentItemIcon(item) {
        const entityInfo = this.metadata.Entities.find(e => e.Name === item.entityName);
        if (entityInfo) {
            return this.getEntityIcon(entityInfo);
        }
        return 'fa-solid fa-file-alt';
    }
    /**
     * Get icon for a favorite item based on its type and entity
     */
    getFavoriteIcon(favorite) {
        if (favorite.type === 'view') {
            return 'fa-solid fa-filter';
        }
        // For entity and record types, look up the entity icon
        if (favorite.entityName) {
            const entityInfo = this.metadata.Entities.find(e => e.Name === favorite.entityName);
            if (entityInfo) {
                return this.getEntityIcon(entityInfo);
            }
        }
        // Fallback icons
        if (favorite.type === 'entity') {
            return 'fa-solid fa-table';
        }
        return 'fa-solid fa-file-alt';
    }
    static ɵfac = function NavigationPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || NavigationPanelComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
    static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: NavigationPanelComponent, selectors: [["mj-explorer-navigation-panel"]], viewQuery: function NavigationPanelComponent_Query(rf, ctx) { if (rf & 1) {
            i0.ɵɵviewQuery(_c0, 5);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.entityTree = _t.first);
        } }, inputs: { entities: "entities", selectedEntityName: "selectedEntityName", favorites: "favorites", recentItems: "recentItems", collapsed: "collapsed", allowedEntityNames: "allowedEntityNames", appEntityGroups: "appEntityGroups", applicationIdFilter: "applicationIdFilter", favoritesSectionExpanded: "favoritesSectionExpanded", recentSectionExpanded: "recentSectionExpanded", entitiesSectionExpanded: "entitiesSectionExpanded", viewsSectionExpanded: "viewsSectionExpanded" }, outputs: { entitySelected: "entitySelected", toggleCollapse: "toggleCollapse", sectionToggled: "sectionToggled", openRecord: "openRecord", selectRecord: "selectRecord", expandAndFocus: "expandAndFocus", appGroupToggled: "appGroupToggled" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 5, vars: 8, consts: [["entityTree", ""], [1, "navigation-panel-container"], [1, "collapse-toggle", 3, "click", "title"], [1, "fa-solid"], [1, "panel-content"], [1, "collapsed-icons"], [1, "section", "favorites-section"], [1, "section-header", 3, "click"], [1, "fa-solid", "fa-star", "section-icon"], [1, "section-title"], [1, "section-count"], [1, "fa-solid", "expand-icon"], [1, "section-content", "scrollable-section"], [1, "section", "recent-section"], [1, "fa-solid", "fa-clock", "section-icon"], [1, "section", "entities-section"], [1, "fa-solid", "fa-database", "section-icon"], [1, "section-content", "entity-tree-container"], [1, "empty-section"], [1, "scrollable-list"], [1, "scrollable-list-inner"], [1, "nav-item", 3, "title"], [1, "nav-item", 3, "click", "title"], [1, "nav-item-label"], [1, "nav-item-content"], [1, "nav-item-meta"], [1, "entity-search"], [1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Search entities...", 1, "search-input", 3, "ngModelChange", "ngModel"], [1, "clear-search"], [3, "SelectionChange", "BranchConfig", "LeafConfig", "SelectionMode", "SelectableTypes", "SelectedIDs", "ShowIcons", "ShowExpandCollapseAll", "AnimateExpandCollapse", "EmptyMessage", "EmptyIcon"], [1, "clear-search", 3, "click"], [1, "fa-solid", "fa-times"], ["title", "Favorites", 1, "icon-btn", 3, "click"], [1, "fa-solid", "fa-star"], [1, "collapsed-badge"], ["title", "Recent", 1, "icon-btn", 3, "click"], [1, "fa-solid", "fa-clock"], ["title", "Entities", 1, "icon-btn", 3, "click"], [1, "fa-solid", "fa-database"]], template: function NavigationPanelComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵelementStart(0, "div", 1)(1, "button", 2);
            i0.ɵɵlistener("click", function NavigationPanelComponent_Template_button_click_1_listener() { return ctx.onToggleCollapse(); });
            i0.ɵɵelement(2, "i", 3);
            i0.ɵɵelementEnd();
            i0.ɵɵconditionalCreate(3, NavigationPanelComponent_Conditional_3_Template, 26, 18, "div", 4)(4, NavigationPanelComponent_Conditional_4_Template, 11, 3, "div", 5);
            i0.ɵɵelementEnd();
        } if (rf & 2) {
            i0.ɵɵclassProp("collapsed", ctx.collapsed);
            i0.ɵɵadvance();
            i0.ɵɵproperty("title", ctx.collapsed ? "Expand" : "Collapse");
            i0.ɵɵadvance();
            i0.ɵɵclassProp("fa-chevron-right", ctx.collapsed)("fa-chevron-left", !ctx.collapsed);
            i0.ɵɵadvance();
            i0.ɵɵconditional(!ctx.collapsed ? 3 : 4);
        } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.TreeComponent], styles: [".navigation-panel-container[_ngcontent-%COMP%] {\n  display: flex;\n  flex-direction: column;\n  height: 100%;\n  min-height: 0; \n\n  position: relative;\n  background: var(--mj-bg-surface);\n  box-shadow: 1px 0 3px rgba(0, 0, 0, 0.05);\n}\n.navigation-panel-container.collapsed[_ngcontent-%COMP%] {\n  align-items: center;\n  padding-top: 48px;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 16px;\n  border-bottom: 1px solid var(--mj-border-default);\n  flex-shrink: 0;\n}\n\n.panel-title[_ngcontent-%COMP%] {\n  font-size: 14px;\n  font-weight: 600;\n  color: var(--mj-text-primary);\n  text-transform: uppercase;\n  letter-spacing: 0.5px;\n}\n\n.collapse-toggle[_ngcontent-%COMP%] {\n  position: absolute;\n  top: 12px;\n  right: 12px;\n  width: 28px;\n  height: 28px;\n  border: none;\n  background: var(--mj-bg-surface-card);\n  border-radius: 6px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: var(--mj-text-secondary);\n  transition: all 0.15s ease;\n  z-index: 10;\n}\n.collapse-toggle[_ngcontent-%COMP%]:hover {\n  background: var(--mj-bg-surface-hover);\n  color: var(--mj-text-primary);\n}\n.collapsed[_ngcontent-%COMP%]   .collapse-toggle[_ngcontent-%COMP%] {\n  right: auto;\n  left: 50%;\n  transform: translateX(-50%);\n  background: transparent;\n}\n.collapsed[_ngcontent-%COMP%]   .collapse-toggle[_ngcontent-%COMP%]:hover {\n  background: var(--mj-bg-surface-card);\n}\n\n.panel-content[_ngcontent-%COMP%] {\n  display: flex;\n  flex-direction: column;\n  height: 100%;\n  overflow: hidden;\n  padding-top: 48px;\n  min-height: 0; \n\n}\n\n.section[_ngcontent-%COMP%] {\n  flex-shrink: 0;\n  border-bottom: 1px solid var(--mj-border-default);\n}\n\n\n\n.section.favorites-section[_ngcontent-%COMP%], \n.section.recent-section[_ngcontent-%COMP%] {\n  display: flex;\n  flex-direction: column;\n  min-height: 0;\n  max-height: 200px; \n\n}\n\n.section.entities-section[_ngcontent-%COMP%] {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  min-height: 0;\n  border-bottom: none;\n}\n\n.section-header[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  padding: 14px 16px;\n  cursor: pointer;\n  user-select: none;\n  transition: background 0.15s ease;\n  background: var(--mj-bg-surface-card);\n}\n.section-header[_ngcontent-%COMP%]:hover {\n  background: var(--mj-bg-surface-sunken);\n}\n\n.section-icon[_ngcontent-%COMP%] {\n  width: 20px;\n  font-size: 13px;\n  color: var(--mj-text-secondary);\n  margin-right: 10px;\n}\n\n.section-title[_ngcontent-%COMP%] {\n  flex: 1;\n  font-size: 11px;\n  font-weight: 700;\n  text-transform: uppercase;\n  letter-spacing: 0.8px;\n  color: var(--mj-text-muted);\n}\n\n.section-count[_ngcontent-%COMP%] {\n  font-size: 11px;\n  color: var(--mj-text-muted);\n  margin-right: 8px;\n  font-weight: 500;\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n  font-size: 10px;\n  color: var(--mj-text-muted);\n  transition: transform 0.15s ease;\n}\n\n.section-content[_ngcontent-%COMP%] {\n  padding: 8px 12px 12px 12px;\n  background: var(--mj-bg-surface);\n}\n\n\n\n.section-content.scrollable-section[_ngcontent-%COMP%] {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  min-height: 0;\n  overflow: hidden;\n}\n\n.scrollable-list[_ngcontent-%COMP%] {\n  flex: 1;\n  overflow-y: auto;\n  min-height: 0;\n  padding-right: 4px;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n  width: 6px;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n  background: transparent;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n  background: var(--mj-border-strong);\n  border-radius: 3px;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n  background: var(--mj-border-strong);\n}\n\n.scrollable-list-inner[_ngcontent-%COMP%] {\n  \n\n}\n\n.entities-section[_ngcontent-%COMP%]   .section-content[_ngcontent-%COMP%] {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  min-height: 0; \n\n  overflow: hidden;\n}\n\n.entity-tree-container[_ngcontent-%COMP%] {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  min-height: 0;\n  overflow: hidden;\n}\n\n.entity-tree-container[_ngcontent-%COMP%]   mj-tree[_ngcontent-%COMP%] {\n  flex: 1;\n  min-height: 0;\n  overflow-y: auto;\n}\n\n.empty-section[_ngcontent-%COMP%] {\n  padding: 20px 16px;\n  text-align: center;\n  color: var(--mj-text-muted);\n  font-size: 12px;\n  font-style: italic;\n}\n\n.nav-item[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  padding: 10px 12px;\n  border-radius: 6px;\n  cursor: pointer;\n  transition: all 0.15s ease;\n  gap: 10px;\n  margin-bottom: 2px;\n}\n.nav-item[_ngcontent-%COMP%]:hover {\n  background: var(--mj-bg-surface-card);\n}\n.nav-item.selected[_ngcontent-%COMP%] {\n  background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n  color: var(--mj-brand-primary);\n  box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.nav-item.selected[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n  color: var(--mj-brand-primary);\n}\n.nav-item.selected[_ngcontent-%COMP%]   .nav-item-label[_ngcontent-%COMP%] {\n  font-weight: 600;\n}\n.nav-item[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n  width: 18px;\n  font-size: 14px;\n  color: var(--mj-text-secondary);\n  flex-shrink: 0;\n  text-align: center;\n}\n\n.nav-item-content[_ngcontent-%COMP%] {\n  flex: 1;\n  min-width: 0;\n  display: flex;\n  flex-direction: column;\n  gap: 2px;\n}\n\n.nav-item-label[_ngcontent-%COMP%] {\n  font-size: 13px;\n  color: var(--mj-text-primary);\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.nav-item-meta[_ngcontent-%COMP%] {\n  font-size: 11px;\n  color: var(--mj-text-muted);\n}\n\n.entity-search[_ngcontent-%COMP%] {\n  position: relative;\n  margin-bottom: 12px;\n  flex-shrink: 0;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n  position: absolute;\n  left: 12px;\n  top: 50%;\n  transform: translateY(-50%);\n  font-size: 12px;\n  color: var(--mj-text-muted);\n}\n\n.search-input[_ngcontent-%COMP%] {\n  width: 100%;\n  padding: 10px 36px 10px 36px;\n  border: 1px solid var(--mj-border-default);\n  border-radius: 8px;\n  font-size: 13px;\n  background: var(--mj-bg-surface-card);\n  transition: all 0.15s ease;\n}\n.search-input[_ngcontent-%COMP%]:focus {\n  outline: none;\n  border-color: var(--mj-brand-primary);\n  background: var(--mj-bg-surface);\n  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n.search-input[_ngcontent-%COMP%]::placeholder {\n  color: var(--mj-text-muted);\n}\n\n.clear-search[_ngcontent-%COMP%] {\n  position: absolute;\n  right: 6px;\n  top: 50%;\n  transform: translateY(-50%);\n  width: 24px;\n  height: 24px;\n  border: none;\n  background: transparent;\n  border-radius: 50%;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: var(--mj-text-muted);\n}\n.clear-search[_ngcontent-%COMP%]:hover {\n  background: var(--mj-border-default);\n  color: var(--mj-text-muted);\n}\n\n.entity-list[_ngcontent-%COMP%] {\n  flex: 1;\n  overflow-y: auto;\n  min-height: 0;\n  padding-right: 4px;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n  width: 6px;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n  background: transparent;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n  background: var(--mj-border-strong);\n  border-radius: 3px;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n  background: var(--mj-border-strong);\n}\n\n.entity-list-inner[_ngcontent-%COMP%] {\n  \n\n  \n\n}\n\n.entity-item[_ngcontent-%COMP%]   .nav-item-label[_ngcontent-%COMP%] {\n  flex: 1;\n}\n\n\n\n\n\n\n.nav-app-group[_ngcontent-%COMP%] {\n  margin-bottom: 2px;\n}\n\n.nav-app-group-header[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  padding: 8px 10px;\n  cursor: pointer;\n  border-radius: 6px;\n  transition: background 0.12s;\n  user-select: none;\n}\n\n.nav-app-group-header[_ngcontent-%COMP%]:hover {\n  background: var(--mj-bg-surface-card);\n}\n\n.nav-app-group-icon[_ngcontent-%COMP%] {\n  font-size: 12px;\n  color: var(--mj-text-secondary);\n  width: 16px;\n  text-align: center;\n  flex-shrink: 0;\n}\n\n.nav-app-group-name[_ngcontent-%COMP%] {\n  font-size: 11px;\n  font-weight: 700;\n  text-transform: uppercase;\n  letter-spacing: 0.5px;\n  color: var(--mj-text-secondary);\n  flex: 1;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.nav-app-group-count[_ngcontent-%COMP%] {\n  font-size: 10px;\n  color: var(--mj-text-muted);\n  background: var(--mj-bg-surface-card);\n  padding: 1px 6px;\n  border-radius: 8px;\n}\n\n.nav-app-group-chevron[_ngcontent-%COMP%] {\n  font-size: 9px;\n  color: var(--mj-text-muted);\n  transition: transform 0.15s;\n}\n\n.nav-app-group-chevron.expanded[_ngcontent-%COMP%] {\n  transform: rotate(90deg);\n}\n\n.nav-app-group-entities[_ngcontent-%COMP%] {\n  padding-left: 8px;\n}\n\n.nav-app-group-entities[_ngcontent-%COMP%]   .nav-item[_ngcontent-%COMP%] {\n  padding: 8px 10px 8px 16px;\n}\n\n.collapsed-icons[_ngcontent-%COMP%] {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 8px;\n  padding-top: 16px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n  width: 36px;\n  height: 36px;\n  border: none;\n  background: transparent;\n  border-radius: 8px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: var(--mj-text-secondary);\n  transition: all 0.15s ease;\n  position: relative;\n}\n.icon-btn[_ngcontent-%COMP%]:hover {\n  background: var(--mj-bg-surface-sunken);\n  color: var(--mj-brand-primary);\n}\n.icon-btn[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n  font-size: 16px;\n}\n\n.collapsed-badge[_ngcontent-%COMP%] {\n  position: absolute;\n  top: 2px;\n  right: 2px;\n  min-width: 16px;\n  height: 16px;\n  font-size: 10px;\n  font-weight: 600;\n  color: var(--mj-text-inverse);\n  background: var(--mj-brand-primary);\n  border-radius: 8px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 0 4px;\n}"] });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NavigationPanelComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'mj-explorer-navigation-panel', template: "<div class=\"navigation-panel-container\" [class.collapsed]=\"collapsed\">\n  <!-- Collapse Toggle -->\n  <button class=\"collapse-toggle\" (click)=\"onToggleCollapse()\" [title]=\"collapsed ? 'Expand' : 'Collapse'\">\n    <i class=\"fa-solid\" [class.fa-chevron-right]=\"collapsed\" [class.fa-chevron-left]=\"!collapsed\"></i>\n  </button>\n\n  @if (!collapsed) {\n    <div class=\"panel-content\">\n      <!-- Favorites Section -->\n      <div class=\"section favorites-section\">\n        <div class=\"section-header\" (click)=\"onSectionToggle('favorites')\">\n          <i class=\"fa-solid fa-star section-icon\"></i>\n          <span class=\"section-title\">Favorites</span>\n          @if (favoriteRecords.length + favoriteEntities.length > 0) {\n            <span class=\"section-count\">({{ favoriteRecords.length + favoriteEntities.length }})</span>\n          }\n          <i class=\"fa-solid expand-icon\" [class.fa-chevron-down]=\"favoritesSectionExpanded\" [class.fa-chevron-right]=\"!favoritesSectionExpanded\"></i>\n        </div>\n\n        @if (favoritesSectionExpanded) {\n          <div class=\"section-content scrollable-section\">\n            @if (favoriteRecords.length + favoriteEntities.length === 0) {\n              <div class=\"empty-section\">\n                <span>No favorites yet</span>\n              </div>\n            } @else {\n              <div class=\"scrollable-list\">\n                <div class=\"scrollable-list-inner\">\n                  @for (favorite of favoriteEntities; track favorite.entityName) {\n                    <div class=\"nav-item\" (click)=\"onFavoriteClick(favorite)\" [title]=\"favorite.entityName ? favorite.entityName + ' - ' + favorite.displayName : favorite.displayName\">\n                      <i [class]=\"getFavoriteIcon(favorite)\"></i>\n                      <span class=\"nav-item-label\">{{ favorite.displayName }}</span>\n                    </div>\n                  }\n                  @for (favorite of favoriteRecords; track favorite.entityName + '|' + favorite.compositeKeyString) {\n                    <div class=\"nav-item\" (click)=\"onFavoriteClick(favorite)\" [title]=\"favorite.entityName ? favorite.entityName + ' - ' + favorite.displayName : favorite.displayName\">\n                      <i [class]=\"getFavoriteIcon(favorite)\"></i>\n                      <span class=\"nav-item-label\">{{ favorite.displayName }}</span>\n                    </div>\n                  }\n                </div>\n              </div>\n            }\n          </div>\n        }\n      </div>\n\n      <!-- Recent Items Section -->\n      <div class=\"section recent-section\">\n        <div class=\"section-header\" (click)=\"onSectionToggle('recent')\">\n          <i class=\"fa-solid fa-clock section-icon\"></i>\n          <span class=\"section-title\">Recent</span>\n          @if (filteredRecentItems.length > 0) {\n            <span class=\"section-count\">({{ filteredRecentItems.length }})</span>\n          }\n          <i class=\"fa-solid expand-icon\" [class.fa-chevron-down]=\"recentSectionExpanded\" [class.fa-chevron-right]=\"!recentSectionExpanded\"></i>\n        </div>\n\n        @if (recentSectionExpanded) {\n          <div class=\"section-content scrollable-section\">\n            @if (filteredRecentItems.length === 0) {\n              <div class=\"empty-section\">\n                <span>No recent items</span>\n              </div>\n            } @else {\n              <div class=\"scrollable-list\">\n                <div class=\"scrollable-list-inner\">\n                  @for (item of filteredRecentItems; track item.entityName + '|' + item.compositeKeyString) {\n                    <div class=\"nav-item\" (click)=\"onRecentClick(item)\" [title]=\"item.entityName + ' - ' + item.displayName\">\n                      <i [class]=\"getRecentItemIcon(item)\"></i>\n                      <div class=\"nav-item-content\">\n                        <span class=\"nav-item-label\">{{ item.displayName }}</span>\n                        <span class=\"nav-item-meta\">{{ formatTimestamp(item.timestamp) }}</span>\n                      </div>\n                    </div>\n                  }\n                </div>\n              </div>\n            }\n          </div>\n        }\n      </div>\n\n      <!-- Entities Section (ng-tree) -->\n      <div class=\"section entities-section\">\n        <div class=\"section-header\" (click)=\"onSectionToggle('entities')\">\n          <i class=\"fa-solid fa-database section-icon\"></i>\n          <span class=\"section-title\">Entities</span>\n          <span class=\"section-count\">({{ entities.length }})</span>\n          <i class=\"fa-solid expand-icon\" [class.fa-chevron-down]=\"entitiesSectionExpanded\" [class.fa-chevron-right]=\"!entitiesSectionExpanded\"></i>\n        </div>\n\n        @if (entitiesSectionExpanded) {\n          <div class=\"section-content entity-tree-container\">\n            <!-- Entity Search -->\n            <div class=\"entity-search\">\n              <i class=\"fa-solid fa-search search-icon\"></i>\n              <input\n                type=\"text\"\n                class=\"search-input\"\n                placeholder=\"Search entities...\"\n                [(ngModel)]=\"entitySearchTerm\"\n                (ngModelChange)=\"onEntitySearchChanged()\"\n              />\n              @if (entitySearchTerm) {\n                <button class=\"clear-search\" (click)=\"clearEntitySearch()\">\n                  <i class=\"fa-solid fa-times\"></i>\n                </button>\n              }\n            </div>\n\n            <!-- Entity Tree -->\n            <mj-tree\n              #entityTree\n              [BranchConfig]=\"treeBranchConfig\"\n              [LeafConfig]=\"treeLeafConfig\"\n              [SelectionMode]=\"'single'\"\n              [SelectableTypes]=\"'leaf'\"\n              [SelectedIDs]=\"selectedEntityIds\"\n              [ShowIcons]=\"true\"\n              [ShowExpandCollapseAll]=\"false\"\n              [AnimateExpandCollapse]=\"true\"\n              [EmptyMessage]=\"entitySearchTerm ? 'No matches for: ' + entitySearchTerm : 'No entities available'\"\n              [EmptyIcon]=\"'fa-solid fa-database'\"\n              (SelectionChange)=\"onTreeEntitySelected($event)\">\n            </mj-tree>\n          </div>\n        }\n      </div>\n    </div>\n  } @else {\n    <!-- Collapsed State - Show Icons Only -->\n    <div class=\"collapsed-icons\">\n      <button class=\"icon-btn\" title=\"Favorites\" (click)=\"onCollapsedIconClick('favorites')\">\n        <i class=\"fa-solid fa-star\"></i>\n        @if (favoriteRecords.length + favoriteEntities.length > 0) {\n          <span class=\"collapsed-badge\">{{ favoriteRecords.length + favoriteEntities.length }}</span>\n        }\n      </button>\n      <button class=\"icon-btn\" title=\"Recent\" (click)=\"onCollapsedIconClick('recent')\">\n        <i class=\"fa-solid fa-clock\"></i>\n        @if (filteredRecentItems.length > 0) {\n          <span class=\"collapsed-badge\">{{ filteredRecentItems.length }}</span>\n        }\n      </button>\n      <button class=\"icon-btn\" title=\"Entities\" (click)=\"onCollapsedIconClick('entities')\">\n        <i class=\"fa-solid fa-database\"></i>\n        <span class=\"collapsed-badge\">{{ entities.length }}</span>\n      </button>\n    </div>\n  }\n</div>\n", styles: [".navigation-panel-container {\n  display: flex;\n  flex-direction: column;\n  height: 100%;\n  min-height: 0; /* Critical for nested flex scrolling */\n  position: relative;\n  background: var(--mj-bg-surface);\n  box-shadow: 1px 0 3px rgba(0, 0, 0, 0.05);\n}\n.navigation-panel-container.collapsed {\n  align-items: center;\n  padding-top: 48px;\n}\n\n.panel-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 16px;\n  border-bottom: 1px solid var(--mj-border-default);\n  flex-shrink: 0;\n}\n\n.panel-title {\n  font-size: 14px;\n  font-weight: 600;\n  color: var(--mj-text-primary);\n  text-transform: uppercase;\n  letter-spacing: 0.5px;\n}\n\n.collapse-toggle {\n  position: absolute;\n  top: 12px;\n  right: 12px;\n  width: 28px;\n  height: 28px;\n  border: none;\n  background: var(--mj-bg-surface-card);\n  border-radius: 6px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: var(--mj-text-secondary);\n  transition: all 0.15s ease;\n  z-index: 10;\n}\n.collapse-toggle:hover {\n  background: var(--mj-bg-surface-hover);\n  color: var(--mj-text-primary);\n}\n.collapsed .collapse-toggle {\n  right: auto;\n  left: 50%;\n  transform: translateX(-50%);\n  background: transparent;\n}\n.collapsed .collapse-toggle:hover {\n  background: var(--mj-bg-surface-card);\n}\n\n.panel-content {\n  display: flex;\n  flex-direction: column;\n  height: 100%;\n  overflow: hidden;\n  padding-top: 48px;\n  min-height: 0; /* Allow flex children to shrink below content size */\n}\n\n.section {\n  flex-shrink: 0;\n  border-bottom: 1px solid var(--mj-border-default);\n}\n\n/* Scrollable sections (Favorites, Recent) - allow them to shrink and scroll */\n.section.favorites-section,\n.section.recent-section {\n  display: flex;\n  flex-direction: column;\n  min-height: 0;\n  max-height: 200px; /* Limit height so entities section has room */\n}\n\n.section.entities-section {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  min-height: 0;\n  border-bottom: none;\n}\n\n.section-header {\n  display: flex;\n  align-items: center;\n  padding: 14px 16px;\n  cursor: pointer;\n  user-select: none;\n  transition: background 0.15s ease;\n  background: var(--mj-bg-surface-card);\n}\n.section-header:hover {\n  background: var(--mj-bg-surface-sunken);\n}\n\n.section-icon {\n  width: 20px;\n  font-size: 13px;\n  color: var(--mj-text-secondary);\n  margin-right: 10px;\n}\n\n.section-title {\n  flex: 1;\n  font-size: 11px;\n  font-weight: 700;\n  text-transform: uppercase;\n  letter-spacing: 0.8px;\n  color: var(--mj-text-muted);\n}\n\n.section-count {\n  font-size: 11px;\n  color: var(--mj-text-muted);\n  margin-right: 8px;\n  font-weight: 500;\n}\n\n.expand-icon {\n  font-size: 10px;\n  color: var(--mj-text-muted);\n  transition: transform 0.15s ease;\n}\n\n.section-content {\n  padding: 8px 12px 12px 12px;\n  background: var(--mj-bg-surface);\n}\n\n/* Scrollable section content for Favorites and Recent */\n.section-content.scrollable-section {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  min-height: 0;\n  overflow: hidden;\n}\n\n.scrollable-list {\n  flex: 1;\n  overflow-y: auto;\n  min-height: 0;\n  padding-right: 4px;\n}\n.scrollable-list::-webkit-scrollbar {\n  width: 6px;\n}\n.scrollable-list::-webkit-scrollbar-track {\n  background: transparent;\n}\n.scrollable-list::-webkit-scrollbar-thumb {\n  background: var(--mj-border-strong);\n  border-radius: 3px;\n}\n.scrollable-list::-webkit-scrollbar-thumb:hover {\n  background: var(--mj-border-strong);\n}\n\n.scrollable-list-inner {\n  /* Inner container grows naturally based on content */\n}\n\n.entities-section .section-content {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  min-height: 0; /* Allow content to shrink */\n  overflow: hidden;\n}\n\n.entity-tree-container {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  min-height: 0;\n  overflow: hidden;\n}\n\n.entity-tree-container mj-tree {\n  flex: 1;\n  min-height: 0;\n  overflow-y: auto;\n}\n\n.empty-section {\n  padding: 20px 16px;\n  text-align: center;\n  color: var(--mj-text-muted);\n  font-size: 12px;\n  font-style: italic;\n}\n\n.nav-item {\n  display: flex;\n  align-items: center;\n  padding: 10px 12px;\n  border-radius: 6px;\n  cursor: pointer;\n  transition: all 0.15s ease;\n  gap: 10px;\n  margin-bottom: 2px;\n}\n.nav-item:hover {\n  background: var(--mj-bg-surface-card);\n}\n.nav-item.selected {\n  background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n  color: var(--mj-brand-primary);\n  box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.nav-item.selected i {\n  color: var(--mj-brand-primary);\n}\n.nav-item.selected .nav-item-label {\n  font-weight: 600;\n}\n.nav-item i {\n  width: 18px;\n  font-size: 14px;\n  color: var(--mj-text-secondary);\n  flex-shrink: 0;\n  text-align: center;\n}\n\n.nav-item-content {\n  flex: 1;\n  min-width: 0;\n  display: flex;\n  flex-direction: column;\n  gap: 2px;\n}\n\n.nav-item-label {\n  font-size: 13px;\n  color: var(--mj-text-primary);\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.nav-item-meta {\n  font-size: 11px;\n  color: var(--mj-text-muted);\n}\n\n.entity-search {\n  position: relative;\n  margin-bottom: 12px;\n  flex-shrink: 0;\n}\n\n.search-icon {\n  position: absolute;\n  left: 12px;\n  top: 50%;\n  transform: translateY(-50%);\n  font-size: 12px;\n  color: var(--mj-text-muted);\n}\n\n.search-input {\n  width: 100%;\n  padding: 10px 36px 10px 36px;\n  border: 1px solid var(--mj-border-default);\n  border-radius: 8px;\n  font-size: 13px;\n  background: var(--mj-bg-surface-card);\n  transition: all 0.15s ease;\n}\n.search-input:focus {\n  outline: none;\n  border-color: var(--mj-brand-primary);\n  background: var(--mj-bg-surface);\n  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n.search-input::placeholder {\n  color: var(--mj-text-muted);\n}\n\n.clear-search {\n  position: absolute;\n  right: 6px;\n  top: 50%;\n  transform: translateY(-50%);\n  width: 24px;\n  height: 24px;\n  border: none;\n  background: transparent;\n  border-radius: 50%;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: var(--mj-text-muted);\n}\n.clear-search:hover {\n  background: var(--mj-border-default);\n  color: var(--mj-text-muted);\n}\n\n.entity-list {\n  flex: 1;\n  overflow-y: auto;\n  min-height: 0;\n  padding-right: 4px;\n}\n.entity-list::-webkit-scrollbar {\n  width: 6px;\n}\n.entity-list::-webkit-scrollbar-track {\n  background: transparent;\n}\n.entity-list::-webkit-scrollbar-thumb {\n  background: var(--mj-border-strong);\n  border-radius: 3px;\n}\n.entity-list::-webkit-scrollbar-thumb:hover {\n  background: var(--mj-border-strong);\n}\n\n.entity-list-inner {\n  /* Inner container grows naturally based on content */\n  /* Does not scroll - parent .entity-list handles scrolling */\n}\n\n.entity-item .nav-item-label {\n  flex: 1;\n}\n\n/* ============================================\n   NAV PANEL APPLICATION GROUPS\n   ============================================ */\n\n.nav-app-group {\n  margin-bottom: 2px;\n}\n\n.nav-app-group-header {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  padding: 8px 10px;\n  cursor: pointer;\n  border-radius: 6px;\n  transition: background 0.12s;\n  user-select: none;\n}\n\n.nav-app-group-header:hover {\n  background: var(--mj-bg-surface-card);\n}\n\n.nav-app-group-icon {\n  font-size: 12px;\n  color: var(--mj-text-secondary);\n  width: 16px;\n  text-align: center;\n  flex-shrink: 0;\n}\n\n.nav-app-group-name {\n  font-size: 11px;\n  font-weight: 700;\n  text-transform: uppercase;\n  letter-spacing: 0.5px;\n  color: var(--mj-text-secondary);\n  flex: 1;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.nav-app-group-count {\n  font-size: 10px;\n  color: var(--mj-text-muted);\n  background: var(--mj-bg-surface-card);\n  padding: 1px 6px;\n  border-radius: 8px;\n}\n\n.nav-app-group-chevron {\n  font-size: 9px;\n  color: var(--mj-text-muted);\n  transition: transform 0.15s;\n}\n\n.nav-app-group-chevron.expanded {\n  transform: rotate(90deg);\n}\n\n.nav-app-group-entities {\n  padding-left: 8px;\n}\n\n.nav-app-group-entities .nav-item {\n  padding: 8px 10px 8px 16px;\n}\n\n.collapsed-icons {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 8px;\n  padding-top: 16px;\n}\n\n.icon-btn {\n  width: 36px;\n  height: 36px;\n  border: none;\n  background: transparent;\n  border-radius: 8px;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: var(--mj-text-secondary);\n  transition: all 0.15s ease;\n  position: relative;\n}\n.icon-btn:hover {\n  background: var(--mj-bg-surface-sunken);\n  color: var(--mj-brand-primary);\n}\n.icon-btn i {\n  font-size: 16px;\n}\n\n.collapsed-badge {\n  position: absolute;\n  top: 2px;\n  right: 2px;\n  min-width: 16px;\n  height: 16px;\n  font-size: 10px;\n  font-weight: 600;\n  color: var(--mj-text-inverse);\n  background: var(--mj-brand-primary);\n  border-radius: 8px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 0 4px;\n}\n"] }]
    }], () => [{ type: i0.ChangeDetectorRef }], { entities: [{
            type: Input
        }], selectedEntityName: [{
            type: Input
        }], favorites: [{
            type: Input
        }], recentItems: [{
            type: Input
        }], collapsed: [{
            type: Input
        }], allowedEntityNames: [{
            type: Input
        }], appEntityGroups: [{
            type: Input
        }], applicationIdFilter: [{
            type: Input
        }], favoritesSectionExpanded: [{
            type: Input
        }], recentSectionExpanded: [{
            type: Input
        }], entitiesSectionExpanded: [{
            type: Input
        }], viewsSectionExpanded: [{
            type: Input
        }], entitySelected: [{
            type: Output
        }], toggleCollapse: [{
            type: Output
        }], sectionToggled: [{
            type: Output
        }], openRecord: [{
            type: Output
        }], selectRecord: [{
            type: Output
        }], expandAndFocus: [{
            type: Output
        }], appGroupToggled: [{
            type: Output
        }], entityTree: [{
            type: ViewChild,
            args: ['entityTree']
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(NavigationPanelComponent, { className: "NavigationPanelComponent", filePath: "src/DataExplorer/components/navigation-panel/navigation-panel.component.ts", lineNumber: 30 }); })();
//# sourceMappingURL=navigation-panel.component.js.map