var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { Component } from '@angular/core';
import { PermissionEngine } from '@memberjunction/core-entities';
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
import { BaseResourceComponent } from '@memberjunction/ng-shared';
import { loadPermissionsUsers, parseAuditFilterParams } from './permissions-shared';
import { buildAuditLogAgentContext, buildPermissionsNotFoundError, resolvePermissionsCandidate, } from './permissions-agent-context';
import { validateStringParam } from '../shared/agent-tool-validation';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@memberjunction/ng-ui-components";
import * as i3 from "@memberjunction/ng-shared-generic";
import * as i4 from "@angular/common";
const _forTrack0 = ($index, $item) => $item.ID;
function PermissionsAuditLogResourceComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "mj-alert", 1);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(ctx_r0.ErrorMessage);
} }
function PermissionsAuditLogResourceComponent_For_11_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "option", 5);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const d_r2 = ctx.$implicit;
    i0.ɵɵproperty("ngValue", d_r2.Name);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(d_r2.Name);
} }
function PermissionsAuditLogResourceComponent_For_18_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "option", 5);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const user_r3 = ctx.$implicit;
    i0.ɵɵproperty("ngValue", user_r3.ID);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(user_r3.Name);
} }
function PermissionsAuditLogResourceComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 18);
    i0.ɵɵtext(1, " Querying... ");
} }
function PermissionsAuditLogResourceComponent_Conditional_27_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 19);
    i0.ɵɵtext(1, " Query ");
} }
function PermissionsAuditLogResourceComponent_Conditional_31_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-loading", 15);
} }
function PermissionsAuditLogResourceComponent_Conditional_32_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 16);
} }
function PermissionsAuditLogResourceComponent_Conditional_33_Template(rf, ctx) { if (rf & 1) {
    const _r4 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "mj-empty-state", 20);
    i0.ɵɵlistener("Action", function PermissionsAuditLogResourceComponent_Conditional_33_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnResetFilters()); });
    i0.ɵɵelementEnd();
} }
function PermissionsAuditLogResourceComponent_Conditional_34_Conditional_4_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 22);
    i0.ɵɵtext(1, "(capped at 500 \u2014 narrow the filters to see more)");
    i0.ɵɵelementEnd();
} }
function PermissionsAuditLogResourceComponent_Conditional_34_For_25_Conditional_19_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span");
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const entry_r5 = i0.ɵɵnextContext().$implicit;
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(entry_r5.Summary);
} }
function PermissionsAuditLogResourceComponent_Conditional_34_For_25_Conditional_20_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 22);
    i0.ɵɵtext(1, "\u2014");
    i0.ɵɵelementEnd();
} }
function PermissionsAuditLogResourceComponent_Conditional_34_For_25_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "tr")(1, "td");
    i0.ɵɵtext(2);
    i0.ɵɵpipe(3, "date");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "td");
    i0.ɵɵtext(5);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(6, "td")(7, "span", 25);
    i0.ɵɵelement(8, "i");
    i0.ɵɵtext(9);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(10, "td");
    i0.ɵɵtext(11);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(12, "td")(13, "span", 22);
    i0.ɵɵtext(14);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(15, "td", 26)(16, "span", 27);
    i0.ɵɵtext(17);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(18, "td");
    i0.ɵɵconditionalCreate(19, PermissionsAuditLogResourceComponent_Conditional_34_For_25_Conditional_19_Template, 2, 1, "span")(20, PermissionsAuditLogResourceComponent_Conditional_34_For_25_Conditional_20_Template, 2, 0, "span", 22);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const entry_r5 = ctx.$implicit;
    const ctx_r0 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 9, entry_r5.ChangedAt, "medium"));
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(entry_r5.ChangedByUserName || entry_r5.ChangedByUserID || "System");
    i0.ɵɵadvance(3);
    i0.ɵɵclassMap(ctx_r0.ChangeIcon(entry_r5.ChangeType));
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" ", entry_r5.ChangeType, " ");
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(entry_r5.DomainName);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(entry_r5.EntityName);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(entry_r5.RecordID);
    i0.ɵɵadvance(2);
    i0.ɵɵconditional(entry_r5.Summary ? 19 : 20);
} }
function PermissionsAuditLogResourceComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 21)(1, "strong");
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵtext(3);
    i0.ɵɵconditionalCreate(4, PermissionsAuditLogResourceComponent_Conditional_34_Conditional_4_Template, 2, 0, "span", 22);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "div", 23)(6, "table", 24)(7, "thead")(8, "tr")(9, "th");
    i0.ɵɵtext(10, "When");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(11, "th");
    i0.ɵɵtext(12, "Who");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(13, "th");
    i0.ɵɵtext(14, "Change");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(15, "th");
    i0.ɵɵtext(16, "Domain");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(17, "th");
    i0.ɵɵtext(18, "Entity");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(19, "th");
    i0.ɵɵtext(20, "Record");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(21, "th");
    i0.ɵɵtext(22, "Summary");
    i0.ɵɵelementEnd()()();
    i0.ɵɵelementStart(23, "tbody");
    i0.ɵɵrepeaterCreate(24, PermissionsAuditLogResourceComponent_Conditional_34_For_25_Template, 21, 12, "tr", null, i0.ɵɵcomponentInstance().TrackByAuditEntry, true);
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext();
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(ctx_r0.Entries.length);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" entr", ctx_r0.Entries.length === 1 ? "y" : "ies", " ");
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r0.Entries.length === 500 ? 4 : -1);
    i0.ɵɵadvance(20);
    i0.ɵɵrepeater(ctx_r0.Entries);
} }
/**
 * Audit Log resource — one of three tabs in the Permissions admin application.
 * Chronological log of Create / Update / Delete events against any permission
 * record across every registered domain. Powered by `PermissionEngine.GetAuditTimeline`.
 */
let PermissionsAuditLogResourceComponent = class PermissionsAuditLogResourceComponent extends BaseResourceComponent {
    cdr;
    Domains = [];
    Users = [];
    DomainFilter = '';
    UserFilter = '';
    StartDate = '';
    EndDate = '';
    Entries = [];
    IsLoading = false;
    HasRunQuery = false;
    ErrorMessage = null;
    constructor(cdr) {
        super();
        this.cdr = cdr;
    }
    async GetResourceDisplayName(_data) {
        return 'Audit Log';
    }
    async GetResourceIconClass(_data) {
        return 'fa-solid fa-clock-rotate-left';
    }
    async ngOnInit() {
        super.ngOnInit();
        this.Domains = PermissionEngine.Instance.Domains;
        try {
            this.Users = await loadPermissionsUsers();
        }
        catch (e) {
            this.ErrorMessage = `Error loading users: ${e instanceof Error ? e.message : String(e)}`;
        }
        this.NotifyLoadComplete();
    }
    ngAfterViewInit() {
        this.registerAgentClientTools();
        this.publishAgentContext();
    }
    ngOnDestroy() {
        super.ngOnDestroy();
    }
    // ================================================================
    // AI Agent Context & Client Tools
    //
    // 🚨 SAFETY BOUNDARY — READ-ONLY / VIEW & FILTER ONLY 🚨
    // The Audit Log is a security-sensitive surface that reveals the history of
    // permission changes. The agent context and client tools registered here are
    // strictly READ-ONLY: run the timeline query with view-only filters (domain,
    // user, date range) and reset those filters. The agent CANNOT create, update,
    // or delete audit records, grant/revoke permissions, mutate any domain,
    // impersonate a user, or bulk-export effective permissions — those operations
    // are DELIBERATELY NOT exposed and must remain human-initiated. Context exposes
    // only the active filter values, the entry count, and the loading flags.
    // ================================================================
    /**
     * Publish the current audit-log state to the AI agent. Re-invoked on every
     * meaningful state change (query run, filter reset). The shaping lives in the
     * pure {@link buildAuditLogAgentContext} helper so it stays unit-testable.
     */
    publishAgentContext() {
        const userFilterName = this.UserFilter
            ? this.Users.find((u) => UUIDsEqual(u.ID, this.UserFilter))?.Name ?? null
            : null;
        const context = buildAuditLogAgentContext({
            DomainFilter: this.DomainFilter,
            UserFilter: this.UserFilter,
            UserFilterName: userFilterName,
            StartDate: this.StartDate,
            EndDate: this.EndDate,
            EntryCount: this.Entries.length,
            RecentEntries: this.Entries.map((e) => ({
                ChangedAt: e.ChangedAt instanceof Date ? e.ChangedAt.toISOString() : String(e.ChangedAt),
                ChangedByUserName: e.ChangedByUserName ?? null,
                DomainName: e.DomainName,
                ChangeType: e.ChangeType,
            })),
            AvailableDomainNames: this.Domains.map((d) => d.Name),
            AvailableUserNames: this.Users.map((u) => u.Name),
            AvailableUserCount: this.Users.length,
            IsLoading: this.IsLoading,
            HasRunQuery: this.HasRunQuery,
        });
        this.navigationService.SetAgentContext(this, context);
    }
    /**
     * Register the read-only / view client tools the agent may invoke. Every
     * Handler is tolerant: validates input and returns
     * `{ Success: false, ErrorMessage }` rather than throwing.
     */
    registerAgentClientTools() {
        this.navigationService.SetAgentClientTools(this, [
            {
                Name: 'RunAuditTimelineQuery',
                Description: 'Run the permission audit timeline with view-only filters and display the matching change history. Read-only — does not create, edit, or delete any record. All filters are optional: domainName, userId, startDate (YYYY-MM-DD), endDate (YYYY-MM-DD).',
                ParameterSchema: {
                    type: 'object',
                    properties: {
                        domainName: { type: 'string', description: 'Limit to a specific permission domain' },
                        userId: { type: 'string', description: 'Limit to changes made by this user ID' },
                        startDate: { type: 'string', description: 'Start of date range (YYYY-MM-DD)' },
                        endDate: { type: 'string', description: 'End of date range (YYYY-MM-DD)' },
                    },
                },
                Handler: async (params) => this.handleRunQueryTool(params),
            },
            {
                Name: 'ResetAuditFilters',
                Description: 'Clear all audit log filters (domain, user, date range) and the displayed results. Read-only — does not mutate any data.',
                ParameterSchema: { type: 'object', properties: {} },
                Handler: async () => this.handleResetFiltersTool(),
            },
            {
                Name: 'SearchAuditEntries',
                Description: 'Read-only: search the currently displayed audit entries by a substring matched against the changing user name, domain, or change type. Returns matching entry summaries — does not modify any record.',
                ParameterSchema: {
                    type: 'object',
                    properties: { query: { type: 'string', description: 'Case-insensitive substring to match against user / domain / change type' } },
                    required: ['query'],
                },
                Handler: async (params) => this.handleSearchEntriesTool(params),
            },
        ]);
    }
    handleSearchEntriesTool(params) {
        const q = validateStringParam(params?.['query'], 'query');
        if (!q.ok)
            return q.result;
        const needle = q.value.trim().toLowerCase();
        if (!needle) {
            return { Success: false, ErrorMessage: 'query is required.' };
        }
        if (this.Entries.length === 0) {
            return { Success: false, ErrorMessage: 'No audit entries are loaded. Run a timeline query first.' };
        }
        const matches = this.Entries.filter((e) => (e.ChangedByUserName ?? '').toLowerCase().includes(needle) ||
            e.DomainName.toLowerCase().includes(needle) ||
            e.ChangeType.toLowerCase().includes(needle));
        return {
            Success: true,
            Data: {
                MatchCount: matches.length,
                Matches: matches.slice(0, 25).map((e) => ({
                    ChangedByUserName: e.ChangedByUserName ?? null,
                    DomainName: e.DomainName,
                    ChangeType: e.ChangeType,
                })),
            },
        };
    }
    async handleRunQueryTool(params) {
        const parsed = parseAuditFilterParams(params);
        if (!parsed.ok) {
            return { Success: false, ErrorMessage: parsed.error };
        }
        // Resolve domain (name or ID) tolerantly.
        let resolvedDomain = '';
        if (parsed.value.DomainName) {
            const domainMatch = resolvePermissionsCandidate(parsed.value.DomainName, this.Domains.map((d) => ({ ID: d.ID, Name: d.Name })));
            if (!domainMatch) {
                return {
                    Success: false,
                    ErrorMessage: buildPermissionsNotFoundError(parsed.value.DomainName, 'permission domain', this.Domains.map((d) => ({ ID: d.ID, Name: d.Name }))),
                };
            }
            resolvedDomain = domainMatch.Name;
        }
        // Resolve user (ID, name, or email) tolerantly; the audit query filters by user ID.
        let resolvedUserId = '';
        if (parsed.value.ChangedByUserID) {
            const userMatch = this.resolveAuditUserRef(parsed.value.ChangedByUserID);
            if (!userMatch) {
                return {
                    Success: false,
                    ErrorMessage: buildPermissionsNotFoundError(parsed.value.ChangedByUserID, 'user', this.Users.map((u) => ({ ID: u.ID, Name: u.Name }))),
                };
            }
            resolvedUserId = userMatch.ID;
        }
        this.DomainFilter = resolvedDomain;
        this.UserFilter = resolvedUserId;
        this.StartDate = parsed.value.StartDate;
        this.EndDate = parsed.value.EndDate;
        await this.OnRunQuery();
        this.publishAgentContext();
        if (this.ErrorMessage) {
            return { Success: false, ErrorMessage: this.ErrorMessage };
        }
        return { Success: true, Data: { EntryCount: this.Entries.length } };
    }
    /** Resolve an audit user-filter reference: id → name → email → name-contains. */
    resolveAuditUserRef(input) {
        const needle = (input ?? '').trim().toLowerCase();
        if (!needle)
            return null;
        const byCandidate = resolvePermissionsCandidate(input, this.Users.map((u) => ({ ID: u.ID, Name: u.Name })));
        if (byCandidate) {
            return this.Users.find((u) => UUIDsEqual(u.ID, byCandidate.ID)) ?? null;
        }
        return (this.Users.find((u) => u.Email.trim().toLowerCase() === needle) ??
            this.Users.find((u) => u.Email.toLowerCase().includes(needle)) ??
            null);
    }
    handleResetFiltersTool() {
        this.OnResetFilters();
        this.publishAgentContext();
        return { Success: true };
    }
    async OnRunQuery() {
        this.ErrorMessage = null;
        this.IsLoading = true;
        this.Entries = [];
        this.cdr.detectChanges();
        try {
            const filter = {
                MaxRows: 500,
            };
            if (this.DomainFilter)
                filter.DomainName = this.DomainFilter;
            if (this.UserFilter)
                filter.ChangedByUserID = this.UserFilter;
            if (this.StartDate)
                filter.StartDate = new Date(this.StartDate);
            if (this.EndDate) {
                // End-of-day semantics — include everything on the selected day
                const d = new Date(this.EndDate);
                d.setHours(23, 59, 59, 999);
                filter.EndDate = d;
            }
            this.Entries = await PermissionEngine.Instance.GetAuditTimeline(filter);
            this.HasRunQuery = true;
        }
        catch (e) {
            this.ErrorMessage = `Error loading audit timeline: ${e instanceof Error ? e.message : String(e)}`;
        }
        this.IsLoading = false;
        this.cdr.detectChanges();
        this.publishAgentContext();
    }
    OnResetFilters() {
        this.DomainFilter = '';
        this.UserFilter = '';
        this.StartDate = '';
        this.EndDate = '';
        this.Entries = [];
        this.HasRunQuery = false;
        this.cdr.detectChanges();
        this.publishAgentContext();
    }
    TrackByAuditEntry(_index, entry) {
        return entry.SourceRecordChangeID;
    }
    ChangeIcon(type) {
        switch (type) {
            case 'Create':
                return 'fa-solid fa-plus';
            case 'Update':
                return 'fa-solid fa-pen';
            case 'Delete':
                return 'fa-solid fa-trash';
            case 'Snapshot':
                return 'fa-solid fa-camera';
            default:
                return 'fa-solid fa-circle';
        }
    }
    static ɵfac = function PermissionsAuditLogResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PermissionsAuditLogResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
    static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PermissionsAuditLogResourceComponent, selectors: [["mj-permissions-audit-log-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 35, vars: 15, consts: [["Title", "Audit Log", "Icon", "fa-solid fa-clock-rotate-left", "Subtitle", "Chronological log of Create / Update / Delete events across every permission domain"], ["Variant", "error"], [1, "selector-row", "wrap"], ["for", "audit-domain-select", 1, "selector-label"], ["id", "audit-domain-select", 1, "mj-input", 3, "ngModelChange", "ngModel", "disabled"], [3, "ngValue"], ["for", "audit-user-select", 1, "selector-label"], ["id", "audit-user-select", 1, "mj-input", 3, "ngModelChange", "ngModel", "disabled"], ["for", "audit-start-date", 1, "selector-label"], ["id", "audit-start-date", "type", "date", 1, "mj-input", 3, "ngModelChange", "ngModel", "disabled"], ["for", "audit-end-date", 1, "selector-label"], ["id", "audit-end-date", "type", "date", 1, "mj-input", 3, "ngModelChange", "ngModel", "disabled"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", "variant", "secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-rotate-left"], ["text", "Loading audit entries...", "size", "medium"], ["Icon", "fa-solid fa-clock-rotate-left", "Title", "No query yet", "Message", "Set your filters and press Query to see audit entries."], ["Variant", "no-results", "Icon", "fa-solid fa-folder-open", "Title", "No audit entries found", "Message", "No audit entries match your filters.", "ActionText", "Reset filters", "ActionIcon", "fa-solid fa-rotate-left"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-magnifying-glass"], ["Variant", "no-results", "Icon", "fa-solid fa-folder-open", "Title", "No audit entries found", "Message", "No audit entries match your filters.", "ActionText", "Reset filters", "ActionIcon", "fa-solid fa-rotate-left", 3, "Action"], [1, "total-summary"], [1, "muted"], [1, "domain-body"], [1, "perms-table"], [1, "action-chip"], [1, "resource-cell"], [1, "resource-id"]], template: function PermissionsAuditLogResourceComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵelementStart(0, "mj-page-layout");
            i0.ɵɵelement(1, "mj-page-header", 0);
            i0.ɵɵelementStart(2, "mj-page-body");
            i0.ɵɵconditionalCreate(3, PermissionsAuditLogResourceComponent_Conditional_3_Template, 2, 1, "mj-alert", 1);
            i0.ɵɵelementStart(4, "div", 2)(5, "label", 3);
            i0.ɵɵtext(6, "Domain:");
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(7, "select", 4);
            i0.ɵɵtwoWayListener("ngModelChange", function PermissionsAuditLogResourceComponent_Template_select_ngModelChange_7_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.DomainFilter, $event) || (ctx.DomainFilter = $event); return $event; });
            i0.ɵɵelementStart(8, "option", 5);
            i0.ɵɵtext(9, "All domains");
            i0.ɵɵelementEnd();
            i0.ɵɵrepeaterCreate(10, PermissionsAuditLogResourceComponent_For_11_Template, 2, 2, "option", 5, _forTrack0);
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(12, "label", 6);
            i0.ɵɵtext(13, "Changed by:");
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(14, "select", 7);
            i0.ɵɵtwoWayListener("ngModelChange", function PermissionsAuditLogResourceComponent_Template_select_ngModelChange_14_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.UserFilter, $event) || (ctx.UserFilter = $event); return $event; });
            i0.ɵɵelementStart(15, "option", 5);
            i0.ɵɵtext(16, "Any user");
            i0.ɵɵelementEnd();
            i0.ɵɵrepeaterCreate(17, PermissionsAuditLogResourceComponent_For_18_Template, 2, 2, "option", 5, _forTrack0);
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(19, "label", 8);
            i0.ɵɵtext(20, "From:");
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(21, "input", 9);
            i0.ɵɵtwoWayListener("ngModelChange", function PermissionsAuditLogResourceComponent_Template_input_ngModelChange_21_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.StartDate, $event) || (ctx.StartDate = $event); return $event; });
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(22, "label", 10);
            i0.ɵɵtext(23, "To:");
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(24, "input", 11);
            i0.ɵɵtwoWayListener("ngModelChange", function PermissionsAuditLogResourceComponent_Template_input_ngModelChange_24_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.EndDate, $event) || (ctx.EndDate = $event); return $event; });
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(25, "button", 12);
            i0.ɵɵlistener("click", function PermissionsAuditLogResourceComponent_Template_button_click_25_listener() { return ctx.OnRunQuery(); });
            i0.ɵɵconditionalCreate(26, PermissionsAuditLogResourceComponent_Conditional_26_Template, 2, 0)(27, PermissionsAuditLogResourceComponent_Conditional_27_Template, 2, 0);
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(28, "button", 13);
            i0.ɵɵlistener("click", function PermissionsAuditLogResourceComponent_Template_button_click_28_listener() { return ctx.OnResetFilters(); });
            i0.ɵɵelement(29, "i", 14);
            i0.ɵɵtext(30, " Reset ");
            i0.ɵɵelementEnd()();
            i0.ɵɵconditionalCreate(31, PermissionsAuditLogResourceComponent_Conditional_31_Template, 1, 0, "mj-loading", 15)(32, PermissionsAuditLogResourceComponent_Conditional_32_Template, 1, 0, "mj-empty-state", 16)(33, PermissionsAuditLogResourceComponent_Conditional_33_Template, 1, 0, "mj-empty-state", 17)(34, PermissionsAuditLogResourceComponent_Conditional_34_Template, 26, 3);
            i0.ɵɵelementEnd()();
        } if (rf & 2) {
            i0.ɵɵadvance(3);
            i0.ɵɵconditional(ctx.ErrorMessage ? 3 : -1);
            i0.ɵɵadvance(4);
            i0.ɵɵtwoWayProperty("ngModel", ctx.DomainFilter);
            i0.ɵɵproperty("disabled", ctx.IsLoading);
            i0.ɵɵadvance();
            i0.ɵɵproperty("ngValue", "");
            i0.ɵɵadvance(2);
            i0.ɵɵrepeater(ctx.Domains);
            i0.ɵɵadvance(4);
            i0.ɵɵtwoWayProperty("ngModel", ctx.UserFilter);
            i0.ɵɵproperty("disabled", ctx.IsLoading);
            i0.ɵɵadvance();
            i0.ɵɵproperty("ngValue", "");
            i0.ɵɵadvance(2);
            i0.ɵɵrepeater(ctx.Users);
            i0.ɵɵadvance(4);
            i0.ɵɵtwoWayProperty("ngModel", ctx.StartDate);
            i0.ɵɵproperty("disabled", ctx.IsLoading);
            i0.ɵɵadvance(3);
            i0.ɵɵtwoWayProperty("ngModel", ctx.EndDate);
            i0.ɵɵproperty("disabled", ctx.IsLoading);
            i0.ɵɵadvance();
            i0.ɵɵproperty("disabled", ctx.IsLoading);
            i0.ɵɵadvance();
            i0.ɵɵconditional(ctx.IsLoading ? 26 : 27);
            i0.ɵɵadvance(2);
            i0.ɵɵproperty("disabled", ctx.IsLoading);
            i0.ɵɵadvance(3);
            i0.ɵɵconditional(ctx.IsLoading ? 31 : !ctx.HasRunQuery ? 32 : ctx.Entries.length === 0 ? 33 : 34);
        } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJButtonDirective, i2.MJPageHeaderComponent, i2.MJPageLayoutComponent, i2.MJPageBodyComponent, i2.MJEmptyStateComponent, i2.MJAlertComponent, i3.LoadingComponent, i4.DatePipe], styles: ["\n\n.tab-bar[_ngcontent-%COMP%] {\n  display: flex;\n  gap: 4px;\n  border-bottom: 1px solid var(--mj-border-default);\n  margin-bottom: 16px;\n}\n\n.tab[_ngcontent-%COMP%] {\n  background: transparent;\n  border: none;\n  padding: 10px 16px;\n  cursor: pointer;\n  color: var(--mj-text-secondary);\n  font: inherit;\n  font-weight: 500;\n  border-bottom: 2px solid transparent;\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n  color: var(--mj-text-primary);\n  background: var(--mj-bg-surface-hover);\n}\n\n.tab-active[_ngcontent-%COMP%] {\n  color: var(--mj-brand-primary);\n  border-bottom-color: var(--mj-brand-primary);\n}\n\n.selector-row.wrap[_ngcontent-%COMP%] {\n  flex-wrap: wrap;\n}\n\n.mj-input.mono[_ngcontent-%COMP%] {\n  font-family: var(--mj-font-mono, monospace);\n  min-width: 300px;\n}\n\n.muted[_ngcontent-%COMP%] {\n  color: var(--mj-text-muted);\n}\n\n\n\n.user-selector-row[_ngcontent-%COMP%], \n.selector-row[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  margin-bottom: 20px;\n  flex-wrap: wrap;\n}\n\n.user-selector-label[_ngcontent-%COMP%], \n.selector-label[_ngcontent-%COMP%] {\n  font-weight: 600;\n  color: var(--mj-text-primary);\n}\n\n#user-select[_ngcontent-%COMP%], \n#domain-select[_ngcontent-%COMP%] {\n  min-width: 320px;\n  flex: 0 1 auto;\n}\n\n.roles-badge[_ngcontent-%COMP%] {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n  padding: 4px 10px;\n  background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n  color: var(--mj-brand-primary);\n  border-radius: 12px;\n  font-size: 12px;\n  font-weight: 500;\n}\n\n.total-summary[_ngcontent-%COMP%] {\n  color: var(--mj-text-secondary);\n  font-size: 13px;\n  margin-bottom: 12px;\n}\n\n.total-summary[_ngcontent-%COMP%]   strong[_ngcontent-%COMP%] {\n  color: var(--mj-text-primary);\n}\n\n\n\n.domain-groups[_ngcontent-%COMP%] {\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n}\n\n\n\n\n.domain-icon[_ngcontent-%COMP%] {\n  color: var(--mj-brand-primary);\n  font-size: 16px;\n}\n\n.domain-name[_ngcontent-%COMP%] {\n  flex: 1;\n  font-weight: 600;\n  font-size: 15px;\n}\n\n\n\n\n\n\n\n\n.domain-body[_ngcontent-%COMP%] {\n  padding: 0;\n  background: var(--mj-bg-surface);\n  overflow-x: auto;\n}\n\n\n\n.perms-table[_ngcontent-%COMP%] {\n  width: 100%;\n  border-collapse: collapse;\n  font-size: 13px;\n}\n\n.perms-table[_ngcontent-%COMP%]   th[_ngcontent-%COMP%], \n.perms-table[_ngcontent-%COMP%]   td[_ngcontent-%COMP%] {\n  padding: 8px 16px;\n  text-align: left;\n  border-bottom: 1px solid var(--mj-border-subtle);\n  vertical-align: top;\n}\n\n.perms-table[_ngcontent-%COMP%]   th[_ngcontent-%COMP%] {\n  background: var(--mj-bg-surface-sunken);\n  color: var(--mj-text-secondary);\n  font-weight: 600;\n  text-transform: uppercase;\n  font-size: 11px;\n  letter-spacing: 0.5px;\n}\n\n.perms-table[_ngcontent-%COMP%]   tbody[_ngcontent-%COMP%]   tr[_ngcontent-%COMP%]:last-child   td[_ngcontent-%COMP%] {\n  border-bottom: none;\n}\n\n.perms-table[_ngcontent-%COMP%]   tbody[_ngcontent-%COMP%]   tr[_ngcontent-%COMP%]:hover {\n  background: var(--mj-bg-surface-hover);\n}\n\n.resource-cell[_ngcontent-%COMP%] {\n  display: flex;\n  flex-direction: column;\n  gap: 2px;\n}\n\n.resource-name[_ngcontent-%COMP%] {\n  color: var(--mj-text-primary);\n  font-weight: 500;\n}\n\n.resource-id[_ngcontent-%COMP%] {\n  color: var(--mj-text-muted);\n  font-size: 11px;\n  font-family: var(--mj-font-mono, monospace);\n}\n\n\n\n.action-chips[_ngcontent-%COMP%] {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 4px;\n}\n\n.action-chip[_ngcontent-%COMP%] {\n  display: inline-flex;\n  align-items: center;\n  padding: 2px 8px;\n  background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n  color: var(--mj-brand-primary);\n  border-radius: 10px;\n  font-size: 11px;\n  font-weight: 500;\n}\n\n\n\n.effect-badge[_ngcontent-%COMP%] {\n  display: inline-flex;\n  align-items: center;\n  padding: 2px 8px;\n  border-radius: 10px;\n  font-size: 11px;\n  font-weight: 600;\n  text-transform: uppercase;\n  letter-spacing: 0.3px;\n}\n\n.effect-allow[_ngcontent-%COMP%] {\n  background: var(--mj-status-success-bg);\n  color: var(--mj-status-success-text);\n}\n\n.effect-deny[_ngcontent-%COMP%] {\n  background: var(--mj-status-error-bg);\n  color: var(--mj-status-error-text);\n}"] });
};
PermissionsAuditLogResourceComponent = __decorate([
    RegisterClass(BaseResourceComponent, 'PermissionsAuditLogResource')
], PermissionsAuditLogResourceComponent);
export { PermissionsAuditLogResourceComponent };
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PermissionsAuditLogResourceComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'mj-permissions-audit-log-resource', template: "<mj-page-layout>\n  <mj-page-header\n    Title=\"Audit Log\"\n    Icon=\"fa-solid fa-clock-rotate-left\"\n    Subtitle=\"Chronological log of Create / Update / Delete events across every permission domain\">\n  </mj-page-header>\n\n  <mj-page-body>\n\n  @if (ErrorMessage) {\n    <mj-alert Variant=\"error\">{{ ErrorMessage }}</mj-alert>\n  }\n\n  <div class=\"selector-row wrap\">\n    <label class=\"selector-label\" for=\"audit-domain-select\">Domain:</label>\n    <select\n      id=\"audit-domain-select\"\n      class=\"mj-input\"\n      [(ngModel)]=\"DomainFilter\"\n      [disabled]=\"IsLoading\"\n    >\n      <option [ngValue]=\"''\">All domains</option>\n      @for (d of Domains; track d.ID) {\n        <option [ngValue]=\"d.Name\">{{ d.Name }}</option>\n      }\n    </select>\n\n    <label class=\"selector-label\" for=\"audit-user-select\">Changed by:</label>\n    <select\n      id=\"audit-user-select\"\n      class=\"mj-input\"\n      [(ngModel)]=\"UserFilter\"\n      [disabled]=\"IsLoading\"\n    >\n      <option [ngValue]=\"''\">Any user</option>\n      @for (user of Users; track user.ID) {\n        <option [ngValue]=\"user.ID\">{{ user.Name }}</option>\n      }\n    </select>\n\n    <label class=\"selector-label\" for=\"audit-start-date\">From:</label>\n    <input\n      id=\"audit-start-date\"\n      type=\"date\"\n      class=\"mj-input\"\n      [(ngModel)]=\"StartDate\"\n      [disabled]=\"IsLoading\"\n    />\n\n    <label class=\"selector-label\" for=\"audit-end-date\">To:</label>\n    <input\n      id=\"audit-end-date\"\n      type=\"date\"\n      class=\"mj-input\"\n      [(ngModel)]=\"EndDate\"\n      [disabled]=\"IsLoading\"\n    />\n\n    <button mjButton variant=\"primary\" (click)=\"OnRunQuery()\" [disabled]=\"IsLoading\">\n      @if (IsLoading) {\n        <i class=\"fa-solid fa-spinner fa-spin\"></i> Querying...\n      } @else {\n        <i class=\"fa-solid fa-magnifying-glass\"></i> Query\n      }\n    </button>\n\n    <button mjButton variant=\"secondary\" (click)=\"OnResetFilters()\" [disabled]=\"IsLoading\">\n      <i class=\"fa-solid fa-rotate-left\"></i> Reset\n    </button>\n  </div>\n\n  @if (IsLoading) {\n    <mj-loading text=\"Loading audit entries...\" size=\"medium\"></mj-loading>\n  } @else if (!HasRunQuery) {\n    <mj-empty-state Icon=\"fa-solid fa-clock-rotate-left\"\n      Title=\"No query yet\"\n      Message=\"Set your filters and press Query to see audit entries.\" />\n  } @else if (Entries.length === 0) {\n    <mj-empty-state Variant=\"no-results\" Icon=\"fa-solid fa-folder-open\"\n      Title=\"No audit entries found\"\n      Message=\"No audit entries match your filters.\"\n      ActionText=\"Reset filters\"\n      ActionIcon=\"fa-solid fa-rotate-left\"\n      (Action)=\"OnResetFilters()\" />\n  } @else {\n    <div class=\"total-summary\">\n      <strong>{{ Entries.length }}</strong> entr{{ Entries.length === 1 ? 'y' : 'ies' }}\n      @if (Entries.length === 500) {\n        <span class=\"muted\">(capped at 500 \u2014 narrow the filters to see more)</span>\n      }\n    </div>\n\n    <div class=\"domain-body\">\n      <table class=\"perms-table\">\n        <thead>\n          <tr>\n            <th>When</th>\n            <th>Who</th>\n            <th>Change</th>\n            <th>Domain</th>\n            <th>Entity</th>\n            <th>Record</th>\n            <th>Summary</th>\n          </tr>\n        </thead>\n        <tbody>\n          @for (entry of Entries; track TrackByAuditEntry($index, entry)) {\n            <tr>\n              <td>{{ entry.ChangedAt | date:'medium' }}</td>\n              <td>{{ entry.ChangedByUserName || entry.ChangedByUserID || 'System' }}</td>\n              <td>\n                <span class=\"action-chip\">\n                  <i [class]=\"ChangeIcon(entry.ChangeType)\"></i>\n                  {{ entry.ChangeType }}\n                </span>\n              </td>\n              <td>{{ entry.DomainName }}</td>\n              <td><span class=\"muted\">{{ entry.EntityName }}</span></td>\n              <td class=\"resource-cell\">\n                <span class=\"resource-id\">{{ entry.RecordID }}</span>\n              </td>\n              <td>\n                @if (entry.Summary) {\n                  <span>{{ entry.Summary }}</span>\n                } @else {\n                  <span class=\"muted\">\u2014</span>\n                }\n              </td>\n            </tr>\n          }\n        </tbody>\n      </table>\n    </div>\n  }\n  </mj-page-body>\n</mj-page-layout>\n", styles: ["/* Tab bar */\n.tab-bar {\n  display: flex;\n  gap: 4px;\n  border-bottom: 1px solid var(--mj-border-default);\n  margin-bottom: 16px;\n}\n\n.tab {\n  background: transparent;\n  border: none;\n  padding: 10px 16px;\n  cursor: pointer;\n  color: var(--mj-text-secondary);\n  font: inherit;\n  font-weight: 500;\n  border-bottom: 2px solid transparent;\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.tab:hover {\n  color: var(--mj-text-primary);\n  background: var(--mj-bg-surface-hover);\n}\n\n.tab-active {\n  color: var(--mj-brand-primary);\n  border-bottom-color: var(--mj-brand-primary);\n}\n\n.selector-row.wrap {\n  flex-wrap: wrap;\n}\n\n.mj-input.mono {\n  font-family: var(--mj-font-mono, monospace);\n  min-width: 300px;\n}\n\n.muted {\n  color: var(--mj-text-muted);\n}\n\n/* User selector (legacy name kept for User Access tab, plus generic selector-row for Resource tab) */\n.user-selector-row,\n.selector-row {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  margin-bottom: 20px;\n  flex-wrap: wrap;\n}\n\n.user-selector-label,\n.selector-label {\n  font-weight: 600;\n  color: var(--mj-text-primary);\n}\n\n#user-select,\n#domain-select {\n  min-width: 320px;\n  flex: 0 1 auto;\n}\n\n.roles-badge {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n  padding: 4px 10px;\n  background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n  color: var(--mj-brand-primary);\n  border-radius: 12px;\n  font-size: 12px;\n  font-weight: 500;\n}\n\n.total-summary {\n  color: var(--mj-text-secondary);\n  font-size: 13px;\n  margin-bottom: 12px;\n}\n\n.total-summary strong {\n  color: var(--mj-text-primary);\n}\n\n/* Domain groups */\n.domain-groups {\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n}\n\n/* Group wrapper + header/chevron chrome now owned by <mj-accordion-panel>. */\n\n.domain-icon {\n  color: var(--mj-brand-primary);\n  font-size: 16px;\n}\n\n.domain-name {\n  flex: 1;\n  font-weight: 600;\n  font-size: 15px;\n}\n\n/* Domain count pill migrated to <mj-accordion-badge mj-accordion-badge--right>;\n   bespoke .domain-count rule removed. */\n\n/* .toggle-icon chevron now owned by <mj-accordion-panel>. */\n\n.domain-body {\n  padding: 0;\n  background: var(--mj-bg-surface);\n  overflow-x: auto;\n}\n\n/* Permissions table */\n.perms-table {\n  width: 100%;\n  border-collapse: collapse;\n  font-size: 13px;\n}\n\n.perms-table th,\n.perms-table td {\n  padding: 8px 16px;\n  text-align: left;\n  border-bottom: 1px solid var(--mj-border-subtle);\n  vertical-align: top;\n}\n\n.perms-table th {\n  background: var(--mj-bg-surface-sunken);\n  color: var(--mj-text-secondary);\n  font-weight: 600;\n  text-transform: uppercase;\n  font-size: 11px;\n  letter-spacing: 0.5px;\n}\n\n.perms-table tbody tr:last-child td {\n  border-bottom: none;\n}\n\n.perms-table tbody tr:hover {\n  background: var(--mj-bg-surface-hover);\n}\n\n.resource-cell {\n  display: flex;\n  flex-direction: column;\n  gap: 2px;\n}\n\n.resource-name {\n  color: var(--mj-text-primary);\n  font-weight: 500;\n}\n\n.resource-id {\n  color: var(--mj-text-muted);\n  font-size: 11px;\n  font-family: var(--mj-font-mono, monospace);\n}\n\n/* Action chips */\n.action-chips {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 4px;\n}\n\n.action-chip {\n  display: inline-flex;\n  align-items: center;\n  padding: 2px 8px;\n  background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n  color: var(--mj-brand-primary);\n  border-radius: 10px;\n  font-size: 11px;\n  font-weight: 500;\n}\n\n/* Effect badge */\n.effect-badge {\n  display: inline-flex;\n  align-items: center;\n  padding: 2px 8px;\n  border-radius: 10px;\n  font-size: 11px;\n  font-weight: 600;\n  text-transform: uppercase;\n  letter-spacing: 0.3px;\n}\n\n.effect-allow {\n  background: var(--mj-status-success-bg);\n  color: var(--mj-status-success-text);\n}\n\n.effect-deny {\n  background: var(--mj-status-error-bg);\n  color: var(--mj-status-error-text);\n}\n"] }]
    }], () => [{ type: i0.ChangeDetectorRef }], null); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PermissionsAuditLogResourceComponent, { className: "PermissionsAuditLogResourceComponent", filePath: "src/Permissions/audit-log-resource.component.ts", lineNumber: 27 }); })();
/** Tree-shaking prevention — referenced from `public-api.ts`. */
export function LoadPermissionsAuditLogResource() {
    // intentionally empty
}
//# sourceMappingURL=audit-log-resource.component.js.map