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;
};
/**
 * @fileoverview Content Autotagging Pipeline Monitor
 *
 * Operations dashboard for monitoring the content autotagging pipeline.
 * Displays KPI metrics, pipeline stage visualization, recent processing feed,
 * and source configuration status.
 */
import { Component, ChangeDetectorRef, inject } from '@angular/core';
import { Subject } from 'rxjs';
import { RunView } from '@memberjunction/core';
import { RegisterClass } from '@memberjunction/global';
import { BaseResourceComponent } from '@memberjunction/ng-shared';
import * as i0 from "@angular/core";
import * as i1 from "@memberjunction/ng-shared-generic";
import * as i2 from "@angular/common";
const _forTrack0 = ($index, $item) => $item.Label;
const _forTrack1 = ($index, $item) => $item.Name;
const _forTrack2 = ($index, $item) => $item.ID;
function AutotaggingPipelineResourceComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 1);
    i0.ɵɵelement(1, "mj-loading", 3);
    i0.ɵɵelementEnd();
} }
function AutotaggingPipelineResourceComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
    const _r1 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 2);
    i0.ɵɵelement(1, "i", 4);
    i0.ɵɵelementStart(2, "span");
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "button", 5);
    i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_2_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.RefreshData()); });
    i0.ɵɵelement(5, "i", 6);
    i0.ɵɵtext(6, " Retry ");
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext();
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(ctx_r1.ErrorMessage);
} }
function AutotaggingPipelineResourceComponent_Conditional_3_For_10_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 26)(1, "div", 27);
    i0.ɵɵelement(2, "i");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 28)(4, "span", 29);
    i0.ɵɵtext(5);
    i0.ɵɵpipe(6, "number");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(7, "span", 30);
    i0.ɵɵtext(8);
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const metric_r4 = ctx.$implicit;
    i0.ɵɵclassMap(metric_r4.ColorClass);
    i0.ɵɵadvance(2);
    i0.ɵɵclassMap(metric_r4.Icon);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(6, 6, metric_r4.Value));
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(metric_r4.Label);
} }
function AutotaggingPipelineResourceComponent_Conditional_3_For_17_Conditional_6_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵtext(0);
} if (rf & 2) {
    const stage_r5 = i0.ɵɵnextContext().$implicit;
    i0.ɵɵtextInterpolate1(" ", stage_r5.ActiveCount, " active ");
} }
function AutotaggingPipelineResourceComponent_Conditional_3_For_17_Conditional_7_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵtext(0, " Idle ");
} }
function AutotaggingPipelineResourceComponent_Conditional_3_For_17_Conditional_9_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 36);
    i0.ɵɵelement(1, "i", 37);
    i0.ɵɵelementEnd();
} }
function AutotaggingPipelineResourceComponent_Conditional_3_For_17_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 31)(1, "div", 32);
    i0.ɵɵelement(2, "i");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "span", 33);
    i0.ɵɵtext(4);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "span", 34);
    i0.ɵɵconditionalCreate(6, AutotaggingPipelineResourceComponent_Conditional_3_For_17_Conditional_6_Template, 1, 1)(7, AutotaggingPipelineResourceComponent_Conditional_3_For_17_Conditional_7_Template, 1, 0);
    i0.ɵɵelementEnd();
    i0.ɵɵelement(8, "div", 35);
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(9, AutotaggingPipelineResourceComponent_Conditional_3_For_17_Conditional_9_Template, 2, 0, "div", 36);
} if (rf & 2) {
    const stage_r5 = ctx.$implicit;
    const ɵ$index_63_r6 = ctx.$index;
    const ɵ$count_63_r7 = ctx.$count;
    i0.ɵɵclassMap("stage-" + stage_r5.Status);
    i0.ɵɵadvance(2);
    i0.ɵɵclassMap(stage_r5.Icon);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(stage_r5.Name);
    i0.ɵɵadvance(2);
    i0.ɵɵconditional(stage_r5.ActiveCount > 0 ? 6 : 7);
    i0.ɵɵadvance(3);
    i0.ɵɵconditional(!(ɵ$index_63_r6 === ɵ$count_63_r7 - 1) ? 9 : -1);
} }
function AutotaggingPipelineResourceComponent_Conditional_3_Conditional_24_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 20);
    i0.ɵɵelement(1, "i", 38);
    i0.ɵɵelementStart(2, "p");
    i0.ɵɵtext(3, "No processed items yet.");
    i0.ɵɵelementEnd()();
} }
function AutotaggingPipelineResourceComponent_Conditional_3_For_26_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 21)(1, "div", 39)(2, "span", 40);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "span", 41);
    i0.ɵɵtext(5);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(6, "div", 42)(7, "span", 43);
    i0.ɵɵelement(8, "i", 44);
    i0.ɵɵtext(9);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(10, "span", 43);
    i0.ɵɵelement(11, "i", 45);
    i0.ɵɵtext(12);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(13, "span", 43);
    i0.ɵɵelement(14, "i", 46);
    i0.ɵɵtext(15);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(16, "span", 47);
    i0.ɵɵtext(17);
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const item_r8 = ctx.$implicit;
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance(2);
    i0.ɵɵproperty("title", item_r8.Name);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(item_r8.Name);
    i0.ɵɵadvance();
    i0.ɵɵclassMap(ctx_r1.GetStatusClass(item_r8.Status));
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" ", item_r8.Status, " ");
    i0.ɵɵadvance(4);
    i0.ɵɵtextInterpolate1(" ", item_r8.SourceName, " ");
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate1(" ", ctx_r1.FormatDuration(item_r8.ProcessingTimeMs), " ");
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate1(" ", item_r8.TagCount, " tags ");
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1(" ", ctx_r1.FormatRelativeTime(item_r8.ProcessedAt), " ");
} }
function AutotaggingPipelineResourceComponent_Conditional_3_Conditional_32_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 20);
    i0.ɵɵelement(1, "i", 48);
    i0.ɵɵelementStart(2, "p");
    i0.ɵɵtext(3, "No sources configured.");
    i0.ɵɵelementEnd()();
} }
function AutotaggingPipelineResourceComponent_Conditional_3_For_34_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 25)(1, "div", 49)(2, "div", 50);
    i0.ɵɵelement(3, "i");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "div", 51)(5, "span", 52);
    i0.ɵɵtext(6);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(7, "span", 53);
    i0.ɵɵtext(8);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(9, "span", 54);
    i0.ɵɵtext(10);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(11, "div", 55)(12, "span", 56);
    i0.ɵɵelement(13, "i", 57);
    i0.ɵɵtext(14);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(15, "span", 56);
    i0.ɵɵelement(16, "i", 58);
    i0.ɵɵtext(17);
    i0.ɵɵpipe(18, "number");
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const source_r9 = ctx.$implicit;
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance(3);
    i0.ɵɵclassMap(source_r9.TypeIcon);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(source_r9.Name);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(source_r9.TypeName);
    i0.ɵɵadvance();
    i0.ɵɵclassMap(ctx_r1.GetStatusClass(source_r9.Status));
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" ", source_r9.Status, " ");
    i0.ɵɵadvance(4);
    i0.ɵɵtextInterpolate1(" ", ctx_r1.FormatRelativeTime(source_r9.LastRunAt), " ");
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(18, 9, source_r9.ItemCount), " items ");
} }
function AutotaggingPipelineResourceComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
    const _r3 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 7)(1, "div", 8);
    i0.ɵɵelement(2, "i", 9);
    i0.ɵɵelementStart(3, "h2");
    i0.ɵɵtext(4, "Content Autotagging Pipeline");
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(5, "button", 5);
    i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_3_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.RefreshData()); });
    i0.ɵɵelement(6, "i", 6);
    i0.ɵɵtext(7, " Refresh ");
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(8, "div", 10);
    i0.ɵɵrepeaterCreate(9, AutotaggingPipelineResourceComponent_Conditional_3_For_10_Template, 9, 8, "div", 11, _forTrack0);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(11, "div", 12)(12, "h3", 13);
    i0.ɵɵelement(13, "i", 14);
    i0.ɵɵtext(14, " Pipeline Stages ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(15, "div", 15);
    i0.ɵɵrepeaterCreate(16, AutotaggingPipelineResourceComponent_Conditional_3_For_17_Template, 10, 7, null, null, _forTrack1);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(18, "div", 16)(19, "div", 17)(20, "h3", 13);
    i0.ɵɵelement(21, "i", 18);
    i0.ɵɵtext(22, " Recent Processing ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(23, "div", 19);
    i0.ɵɵconditionalCreate(24, AutotaggingPipelineResourceComponent_Conditional_3_Conditional_24_Template, 4, 0, "div", 20);
    i0.ɵɵrepeaterCreate(25, AutotaggingPipelineResourceComponent_Conditional_3_For_26_Template, 18, 9, "div", 21, i0.ɵɵrepeaterTrackByIndex);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(27, "div", 22)(28, "h3", 13);
    i0.ɵɵelement(29, "i", 23);
    i0.ɵɵtext(30, " Content Sources ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(31, "div", 24);
    i0.ɵɵconditionalCreate(32, AutotaggingPipelineResourceComponent_Conditional_3_Conditional_32_Template, 4, 0, "div", 20);
    i0.ɵɵrepeaterCreate(33, AutotaggingPipelineResourceComponent_Conditional_3_For_34_Template, 19, 11, "div", 25, _forTrack2);
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext();
    i0.ɵɵadvance(9);
    i0.ɵɵrepeater(ctx_r1.KPIMetrics);
    i0.ɵɵadvance(7);
    i0.ɵɵrepeater(ctx_r1.PipelineStages);
    i0.ɵɵadvance(8);
    i0.ɵɵconditional(ctx_r1.ProcessedItems.length === 0 ? 24 : -1);
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r1.ProcessedItems);
    i0.ɵɵadvance(7);
    i0.ɵɵconditional(ctx_r1.ContentSources.length === 0 ? 32 : -1);
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r1.ContentSources);
} }
let AutotaggingPipelineResourceComponent = class AutotaggingPipelineResourceComponent extends BaseResourceComponent {
    destroy$ = new Subject();
    IsLoading = false;
    ErrorMessage = '';
    // KPI data
    KPIMetrics = [];
    // Pipeline stages
    PipelineStages = [];
    // Recent processing feed
    ProcessedItems = [];
    // Source configuration
    ContentSources = [];
    // Raw data holders for aggregation
    contentItems = [];
    contentRuns = [];
    contentTags = [];
    contentSourceTypes = [];
    contentSourcesRaw = [];
    cdr = inject(ChangeDetectorRef);
    async ngAfterViewInit() {
        await this.LoadData();
        this.NotifyLoadComplete();
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    async GetResourceDisplayName(_data) {
        return 'Content Autotagging';
    }
    async GetResourceIconClass(_data) {
        return 'fa-solid fa-tags';
    }
    /** Load all pipeline data from MJ entities */
    async LoadData() {
        this.IsLoading = true;
        this.ErrorMessage = '';
        this.cdr.detectChanges();
        try {
            const rv = new RunView();
            const [sourcesResult, itemsResult, runsResult, tagsResult, typesResult] = await rv.RunViews([
                {
                    EntityName: 'MJ: Content Sources',
                    OrderBy: 'Name',
                    ResultType: 'simple'
                },
                {
                    EntityName: 'MJ: Content Items',
                    OrderBy: '__mj_CreatedAt DESC',
                    MaxRows: 200,
                    ResultType: 'simple'
                },
                {
                    EntityName: 'MJ: Content Process Runs',
                    OrderBy: '__mj_CreatedAt DESC',
                    MaxRows: 100,
                    ResultType: 'simple'
                },
                {
                    EntityName: 'MJ: Content Item Tags',
                    ResultType: 'simple'
                },
                {
                    EntityName: 'MJ: Content Source Types',
                    ResultType: 'simple'
                }
            ]);
            this.contentSourcesRaw = sourcesResult.Success ? sourcesResult.Results : [];
            this.contentItems = itemsResult.Success ? itemsResult.Results : [];
            this.contentRuns = runsResult.Success ? runsResult.Results : [];
            this.contentTags = tagsResult.Success ? tagsResult.Results : [];
            this.contentSourceTypes = typesResult.Success ? typesResult.Results : [];
            this.buildKPIMetrics();
            this.buildPipelineStages();
            this.buildProcessedItems();
            this.buildContentSources();
        }
        catch (error) {
            console.error('Error loading autotagging pipeline data:', error);
            this.ErrorMessage = 'Failed to load pipeline data. Please try again.';
        }
        finally {
            this.IsLoading = false;
            this.cdr.detectChanges();
        }
    }
    /** Refresh pipeline status data */
    async RefreshData() {
        await this.LoadData();
    }
    /** Format milliseconds into a human-readable duration */
    FormatDuration(ms) {
        if (ms < 1000)
            return `${ms}ms`;
        if (ms < 60000)
            return `${(ms / 1000).toFixed(1)}s`;
        return `${(ms / 60000).toFixed(1)}m`;
    }
    /** Format a date as a relative time string */
    FormatRelativeTime(date) {
        if (!date)
            return 'Never';
        const now = new Date();
        const diffMs = now.getTime() - new Date(date).getTime();
        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);
        return `${diffDays}d ago`;
    }
    /** Get CSS class for a processing status */
    GetStatusClass(status) {
        switch (status) {
            case 'Complete':
            case 'Active':
                return 'status-success';
            case 'Processing':
                return 'status-processing';
            case 'Error':
                return 'status-error';
            case 'Paused':
                return 'status-warning';
            default:
                return 'status-default';
        }
    }
    /** Get icon for a source type */
    GetSourceTypeIcon(typeName) {
        const iconMap = {
            'Web': 'fa-solid fa-globe',
            'API': 'fa-solid fa-plug',
            'Database': 'fa-solid fa-database',
            'File': 'fa-solid fa-file-alt',
            'Email': 'fa-solid fa-envelope',
            'RSS': 'fa-solid fa-rss',
            'CMS': 'fa-solid fa-newspaper'
        };
        return iconMap[typeName] ?? 'fa-solid fa-folder';
    }
    // ---- Private Methods ----
    /** Build KPI metrics from loaded data */
    buildKPIMetrics() {
        const activeSources = this.contentSourcesRaw.filter((s) => s['Status'] === 'Active').length;
        const totalItems = this.contentItems.length;
        const totalTags = this.contentTags.length;
        const errorCount = this.contentRuns.filter((r) => r['Status'] === 'Error').length;
        this.KPIMetrics = [
            {
                Label: 'Active Sources',
                Value: activeSources,
                Icon: 'fa-solid fa-satellite-dish',
                ColorClass: 'kpi-brand'
            },
            {
                Label: 'Items Processed',
                Value: totalItems,
                Icon: 'fa-solid fa-file-lines',
                ColorClass: 'kpi-info'
            },
            {
                Label: 'Tags Generated',
                Value: totalTags,
                Icon: 'fa-solid fa-tags',
                ColorClass: 'kpi-success'
            },
            {
                Label: 'Errors',
                Value: errorCount,
                Icon: 'fa-solid fa-circle-exclamation',
                ColorClass: errorCount > 0 ? 'kpi-error' : 'kpi-success'
            }
        ];
    }
    /** Build pipeline stage visualization data */
    buildPipelineStages() {
        const runsByStage = this.groupRunsByStage();
        this.PipelineStages = [
            this.createStage('Ingest', 'fa-solid fa-download', runsByStage),
            this.createStage('Extract', 'fa-solid fa-file-export', runsByStage),
            this.createStage('Chunk', 'fa-solid fa-puzzle-piece', runsByStage),
            this.createStage('Tag', 'fa-solid fa-tag', runsByStage),
            this.createStage('Vectorize', 'fa-solid fa-vector-square', runsByStage)
        ];
    }
    /** Group content runs by their processing stage */
    groupRunsByStage() {
        const groups = new Map();
        for (const run of this.contentRuns) {
            const stage = run['Stage'] ?? 'Unknown';
            const existing = groups.get(stage) ?? [];
            existing.push(run);
            groups.set(stage, existing);
        }
        return groups;
    }
    /** Create a pipeline stage object from run data */
    createStage(name, icon, runsByStage) {
        const stageRuns = runsByStage.get(name) ?? [];
        const activeRuns = stageRuns.filter((r) => r['Status'] === 'Processing' || r['Status'] === 'Running');
        const errorRuns = stageRuns.filter((r) => r['Status'] === 'Error');
        let status = 'idle';
        if (errorRuns.length > 0)
            status = 'error';
        else if (activeRuns.length > 0)
            status = 'active';
        return { Name: name, Icon: icon, ActiveCount: activeRuns.length, Status: status };
    }
    /** Build the recent processing feed from content items and tags */
    buildProcessedItems() {
        const tagCountByItem = this.countTagsByItem();
        this.ProcessedItems = this.contentItems.slice(0, 50).map((item) => {
            const itemId = item['ID'];
            return {
                Name: item['Name'] ?? 'Unnamed Item',
                SourceName: item['ContentSource'] ?? item['ContentSourceID'] ?? 'Unknown',
                ProcessingTimeMs: item['ProcessingTimeMs'] ?? 0,
                Status: this.mapItemStatus(item['Status']),
                TagCount: tagCountByItem.get(itemId) ?? 0,
                ProcessedAt: item['__mj_CreatedAt'] ? new Date(item['__mj_CreatedAt']) : new Date()
            };
        });
    }
    /** Count tags per content item */
    countTagsByItem() {
        const counts = new Map();
        for (const tag of this.contentTags) {
            const itemId = tag['ContentItemID'];
            if (itemId) {
                counts.set(itemId, (counts.get(itemId) ?? 0) + 1);
            }
        }
        return counts;
    }
    /** Map raw status values to display status */
    mapItemStatus(status) {
        if (!status)
            return 'Processing';
        const normalized = status.toLowerCase();
        if (normalized === 'complete' || normalized === 'completed' || normalized === 'done')
            return 'Complete';
        if (normalized === 'error' || normalized === 'failed')
            return 'Error';
        return 'Processing';
    }
    /** Build content source summaries from raw data */
    buildContentSources() {
        const typeMap = this.buildTypeMap();
        const itemCountBySource = this.countItemsBySource();
        this.ContentSources = this.contentSourcesRaw.map((source) => {
            const typeId = source['ContentSourceTypeID'];
            const typeName = typeMap.get(typeId) ?? 'Unknown';
            return {
                ID: source['ID'],
                Name: source['Name'] ?? 'Unnamed Source',
                TypeName: typeName,
                TypeIcon: this.GetSourceTypeIcon(typeName),
                Status: this.mapSourceStatus(source['Status']),
                LastRunAt: source['LastRunAt'] ? new Date(source['LastRunAt']) : null,
                ItemCount: itemCountBySource.get(source['ID']) ?? 0
            };
        });
    }
    /** Build a map of source type IDs to names */
    buildTypeMap() {
        const map = new Map();
        for (const type of this.contentSourceTypes) {
            map.set(type['ID'], type['Name'] ?? 'Unknown');
        }
        return map;
    }
    /** Count content items per source */
    countItemsBySource() {
        const counts = new Map();
        for (const item of this.contentItems) {
            const sourceId = item['ContentSourceID'];
            if (sourceId) {
                counts.set(sourceId, (counts.get(sourceId) ?? 0) + 1);
            }
        }
        return counts;
    }
    /** Map raw source status to display status */
    mapSourceStatus(status) {
        if (!status)
            return 'Paused';
        const normalized = status.toLowerCase();
        if (normalized === 'active' || normalized === 'running')
            return 'Active';
        if (normalized === 'error' || normalized === 'failed')
            return 'Error';
        return 'Paused';
    }
    static ɵfac = /*@__PURE__*/ (() => { let ɵAutotaggingPipelineResourceComponent_BaseFactory; return function AutotaggingPipelineResourceComponent_Factory(__ngFactoryType__) { return (ɵAutotaggingPipelineResourceComponent_BaseFactory || (ɵAutotaggingPipelineResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(AutotaggingPipelineResourceComponent)))(__ngFactoryType__ || AutotaggingPipelineResourceComponent); }; })();
    static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AutotaggingPipelineResourceComponent, selectors: [["app-autotagging-pipeline-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 3, consts: [[1, "autotagging-container"], [1, "loading-overlay"], [1, "error-banner"], ["text", "Loading pipeline data..."], [1, "fa-solid", "fa-triangle-exclamation"], [1, "refresh-btn", 3, "click"], [1, "fa-solid", "fa-rotate-right"], [1, "header-row"], [1, "header-title"], [1, "fa-solid", "fa-tags", "header-icon"], [1, "kpi-strip"], [1, "kpi-card", 3, "class"], [1, "pipeline-section"], [1, "section-title"], [1, "fa-solid", "fa-diagram-project"], [1, "pipeline-flow"], [1, "main-content"], [1, "feed-section"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "feed-list"], [1, "empty-state"], [1, "feed-item"], [1, "sources-panel"], [1, "fa-solid", "fa-gear"], [1, "sources-list"], [1, "source-card"], [1, "kpi-card"], [1, "kpi-icon"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "pipeline-stage"], [1, "stage-icon"], [1, "stage-name"], [1, "stage-count"], [1, "stage-indicator"], [1, "stage-connector"], [1, "fa-solid", "fa-chevron-right"], [1, "fa-solid", "fa-inbox"], [1, "feed-item-header"], [1, "feed-item-name", 3, "title"], [1, "feed-item-status"], [1, "feed-item-details"], [1, "feed-detail"], [1, "fa-solid", "fa-database"], [1, "fa-solid", "fa-stopwatch"], [1, "fa-solid", "fa-tags"], [1, "feed-detail", "feed-time"], [1, "fa-solid", "fa-plug-circle-xmark"], [1, "source-header"], [1, "source-icon"], [1, "source-info"], [1, "source-name"], [1, "source-type"], [1, "source-status"], [1, "source-meta"], [1, "source-meta-item"], [1, "fa-solid", "fa-clock"], [1, "fa-solid", "fa-file-lines"]], template: function AutotaggingPipelineResourceComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵelementStart(0, "div", 0);
            i0.ɵɵconditionalCreate(1, AutotaggingPipelineResourceComponent_Conditional_1_Template, 2, 0, "div", 1);
            i0.ɵɵconditionalCreate(2, AutotaggingPipelineResourceComponent_Conditional_2_Template, 7, 1, "div", 2);
            i0.ɵɵconditionalCreate(3, AutotaggingPipelineResourceComponent_Conditional_3_Template, 35, 2);
            i0.ɵɵelementEnd();
        } if (rf & 2) {
            i0.ɵɵadvance();
            i0.ɵɵconditional(ctx.IsLoading ? 1 : -1);
            i0.ɵɵadvance();
            i0.ɵɵconditional(ctx.ErrorMessage ? 2 : -1);
            i0.ɵɵadvance();
            i0.ɵɵconditional(!ctx.IsLoading ? 3 : -1);
        } }, dependencies: [i1.LoadingComponent, i2.DecimalPipe], styles: ["\n\n\n\n\n\n[_nghost-%COMP%] {\n    display: block;\n    height: 100%;\n    overflow: hidden;\n}\n\n\n\n\n.autotagging-container[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    height: 100%;\n    padding: 20px;\n    gap: 20px;\n    overflow-y: auto;\n    background: var(--mj-bg-page);\n    color: var(--mj-text-primary);\n}\n\n\n\n\n.loading-overlay[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    height: 200px;\n}\n\n.error-banner[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    padding: 12px 16px;\n    border-radius: 6px;\n    background: var(--mj-status-error-bg);\n    color: var(--mj-status-error-text);\n    border: 1px solid var(--mj-status-error-border);\n}\n\n.error-banner[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 16px;\n}\n\n.error-banner[_ngcontent-%COMP%]   span[_ngcontent-%COMP%] {\n    flex: 1;\n}\n\n\n\n\n.header-row[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n}\n\n.header-title[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n}\n\n.header-icon[_ngcontent-%COMP%] {\n    font-size: 20px;\n    color: var(--mj-brand-primary);\n}\n\n.header-title[_ngcontent-%COMP%]   h2[_ngcontent-%COMP%] {\n    margin: 0;\n    font-size: 20px;\n    font-weight: 600;\n    color: var(--mj-text-primary);\n}\n\n.refresh-btn[_ngcontent-%COMP%] {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    padding: 8px 14px;\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    background: var(--mj-bg-surface);\n    color: var(--mj-text-secondary);\n    cursor: pointer;\n    font-size: 13px;\n    transition: background 0.15s, border-color 0.15s;\n}\n\n.refresh-btn[_ngcontent-%COMP%]:hover {\n    background: var(--mj-bg-surface-hover);\n    border-color: var(--mj-border-strong);\n}\n\n\n\n\n.kpi-strip[_ngcontent-%COMP%] {\n    display: grid;\n    grid-template-columns: repeat(4, 1fr);\n    gap: 16px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 14px;\n    padding: 16px;\n    border-radius: 8px;\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-subtle);\n    transition: box-shadow 0.15s;\n}\n\n.kpi-card[_ngcontent-%COMP%]:hover {\n    box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    width: 44px;\n    height: 44px;\n    border-radius: 10px;\n    font-size: 18px;\n    flex-shrink: 0;\n}\n\n.kpi-brand[_ngcontent-%COMP%]   .kpi-icon[_ngcontent-%COMP%] {\n    background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n    color: var(--mj-brand-primary);\n}\n\n.kpi-info[_ngcontent-%COMP%]   .kpi-icon[_ngcontent-%COMP%] {\n    background: color-mix(in srgb, var(--mj-status-info) 12%, var(--mj-bg-surface));\n    color: var(--mj-status-info);\n}\n\n.kpi-success[_ngcontent-%COMP%]   .kpi-icon[_ngcontent-%COMP%] {\n    background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n    color: var(--mj-status-success);\n}\n\n.kpi-error[_ngcontent-%COMP%]   .kpi-icon[_ngcontent-%COMP%] {\n    background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n    color: var(--mj-status-error);\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n    font-size: 22px;\n    font-weight: 700;\n    line-height: 1.2;\n    color: var(--mj-text-primary);\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n    font-size: 12px;\n    color: var(--mj-text-muted);\n    text-transform: uppercase;\n    letter-spacing: 0.04em;\n}\n\n\n\n\n.pipeline-section[_ngcontent-%COMP%] {\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-subtle);\n    border-radius: 8px;\n    padding: 18px 20px;\n}\n\n.section-title[_ngcontent-%COMP%] {\n    margin: 0 0 14px 0;\n    font-size: 14px;\n    font-weight: 600;\n    color: var(--mj-text-secondary);\n    display: flex;\n    align-items: center;\n    gap: 8px;\n}\n\n.section-title[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    color: var(--mj-text-muted);\n}\n\n.pipeline-flow[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 8px;\n    flex-wrap: wrap;\n}\n\n.pipeline-stage[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    gap: 6px;\n    padding: 14px 20px;\n    border-radius: 8px;\n    background: var(--mj-bg-surface-card);\n    border: 1px solid var(--mj-border-subtle);\n    min-width: 100px;\n    position: relative;\n    transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.stage-icon[_ngcontent-%COMP%] {\n    font-size: 20px;\n    color: var(--mj-text-muted);\n}\n\n.stage-name[_ngcontent-%COMP%] {\n    font-size: 13px;\n    font-weight: 600;\n    color: var(--mj-text-primary);\n}\n\n.stage-count[_ngcontent-%COMP%] {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n.stage-indicator[_ngcontent-%COMP%] {\n    position: absolute;\n    bottom: 0;\n    left: 10%;\n    right: 10%;\n    height: 3px;\n    border-radius: 3px 3px 0 0;\n    background: var(--mj-border-subtle);\n    transition: background 0.2s;\n}\n\n\n\n\n.stage-active[_ngcontent-%COMP%] {\n    border-color: var(--mj-brand-primary);\n    box-shadow: 0 0 0 1px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.stage-active[_ngcontent-%COMP%]   .stage-icon[_ngcontent-%COMP%] {\n    color: var(--mj-brand-primary);\n}\n\n.stage-active[_ngcontent-%COMP%]   .stage-count[_ngcontent-%COMP%] {\n    color: var(--mj-brand-primary);\n    font-weight: 600;\n}\n\n.stage-active[_ngcontent-%COMP%]   .stage-indicator[_ngcontent-%COMP%] {\n    background: var(--mj-brand-primary);\n}\n\n.stage-error[_ngcontent-%COMP%] {\n    border-color: var(--mj-status-error);\n}\n\n.stage-error[_ngcontent-%COMP%]   .stage-icon[_ngcontent-%COMP%] {\n    color: var(--mj-status-error);\n}\n\n.stage-error[_ngcontent-%COMP%]   .stage-indicator[_ngcontent-%COMP%] {\n    background: var(--mj-status-error);\n}\n\n.stage-connector[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    color: var(--mj-text-disabled);\n    font-size: 12px;\n}\n\n\n\n\n.main-content[_ngcontent-%COMP%] {\n    display: grid;\n    grid-template-columns: 1fr 320px;\n    gap: 20px;\n    flex: 1;\n    min-height: 0;\n}\n\n\n\n\n.feed-section[_ngcontent-%COMP%] {\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-subtle);\n    border-radius: 8px;\n    padding: 18px 20px;\n    display: flex;\n    flex-direction: column;\n    min-height: 0;\n}\n\n.feed-list[_ngcontent-%COMP%] {\n    flex: 1;\n    overflow-y: auto;\n    display: flex;\n    flex-direction: column;\n    gap: 2px;\n}\n\n.feed-item[_ngcontent-%COMP%] {\n    padding: 10px 12px;\n    border-radius: 6px;\n    transition: background 0.1s;\n}\n\n.feed-item[_ngcontent-%COMP%]:hover {\n    background: var(--mj-bg-surface-hover);\n}\n\n.feed-item-header[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 4px;\n}\n\n.feed-item-name[_ngcontent-%COMP%] {\n    font-size: 13px;\n    font-weight: 500;\n    color: var(--mj-text-primary);\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    max-width: 70%;\n}\n\n.feed-item-status[_ngcontent-%COMP%] {\n    font-size: 11px;\n    font-weight: 600;\n    padding: 2px 8px;\n    border-radius: 10px;\n    text-transform: uppercase;\n    letter-spacing: 0.03em;\n}\n\n.feed-item-details[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 14px;\n    flex-wrap: wrap;\n}\n\n.feed-detail[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n.feed-detail[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 10px;\n}\n\n.feed-time[_ngcontent-%COMP%] {\n    margin-left: auto;\n}\n\n\n\n\n.sources-panel[_ngcontent-%COMP%] {\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-subtle);\n    border-radius: 8px;\n    padding: 18px 20px;\n    display: flex;\n    flex-direction: column;\n    min-height: 0;\n}\n\n.sources-list[_ngcontent-%COMP%] {\n    flex: 1;\n    overflow-y: auto;\n    display: flex;\n    flex-direction: column;\n    gap: 10px;\n}\n\n.source-card[_ngcontent-%COMP%] {\n    padding: 12px;\n    border-radius: 6px;\n    background: var(--mj-bg-surface-card);\n    border: 1px solid var(--mj-border-subtle);\n    transition: border-color 0.15s;\n}\n\n.source-card[_ngcontent-%COMP%]:hover {\n    border-color: var(--mj-border-default);\n}\n\n.source-header[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    margin-bottom: 8px;\n}\n\n.source-icon[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    width: 32px;\n    height: 32px;\n    border-radius: 6px;\n    background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n    color: var(--mj-brand-primary);\n    font-size: 14px;\n    flex-shrink: 0;\n}\n\n.source-info[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    flex: 1;\n    min-width: 0;\n}\n\n.source-name[_ngcontent-%COMP%] {\n    font-size: 13px;\n    font-weight: 600;\n    color: var(--mj-text-primary);\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n}\n\n.source-type[_ngcontent-%COMP%] {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n.source-status[_ngcontent-%COMP%] {\n    font-size: 11px;\n    font-weight: 600;\n    padding: 2px 8px;\n    border-radius: 10px;\n    text-transform: uppercase;\n    letter-spacing: 0.03em;\n    flex-shrink: 0;\n}\n\n.source-meta[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 14px;\n}\n\n.source-meta-item[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n.source-meta-item[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 10px;\n}\n\n\n\n\n.status-success[_ngcontent-%COMP%] {\n    background: var(--mj-status-success-bg);\n    color: var(--mj-status-success-text);\n    border: 1px solid var(--mj-status-success-border);\n}\n\n.status-processing[_ngcontent-%COMP%] {\n    background: var(--mj-status-info-bg);\n    color: var(--mj-status-info-text);\n    border: 1px solid var(--mj-status-info-border);\n}\n\n.status-error[_ngcontent-%COMP%] {\n    background: var(--mj-status-error-bg);\n    color: var(--mj-status-error-text);\n    border: 1px solid var(--mj-status-error-border);\n}\n\n.status-warning[_ngcontent-%COMP%] {\n    background: var(--mj-status-warning-bg);\n    color: var(--mj-status-warning-text);\n    border: 1px solid var(--mj-status-warning-border);\n}\n\n.status-default[_ngcontent-%COMP%] {\n    background: var(--mj-bg-surface-sunken);\n    color: var(--mj-text-muted);\n    border: 1px solid var(--mj-border-subtle);\n}\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    gap: 8px;\n    padding: 32px 16px;\n    color: var(--mj-text-disabled);\n}\n\n.empty-state[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 28px;\n}\n\n.empty-state[_ngcontent-%COMP%]   p[_ngcontent-%COMP%] {\n    margin: 0;\n    font-size: 13px;\n}\n\n\n\n\n@media (max-width: 1100px) {\n    .main-content[_ngcontent-%COMP%] {\n        grid-template-columns: 1fr;\n    }\n}\n\n@media (max-width: 768px) {\n    .kpi-strip[_ngcontent-%COMP%] {\n        grid-template-columns: repeat(2, 1fr);\n    }\n\n    .pipeline-flow[_ngcontent-%COMP%] {\n        gap: 6px;\n    }\n\n    .pipeline-stage[_ngcontent-%COMP%] {\n        min-width: 80px;\n        padding: 10px 12px;\n    }\n}\n\n@media (max-width: 480px) {\n    .kpi-strip[_ngcontent-%COMP%] {\n        grid-template-columns: 1fr;\n    }\n\n    .pipeline-stage[_ngcontent-%COMP%] {\n        min-width: 70px;\n    }\n\n    .header-row[_ngcontent-%COMP%] {\n        flex-direction: column;\n        align-items: flex-start;\n        gap: 10px;\n    }\n}"] });
};
AutotaggingPipelineResourceComponent = __decorate([
    RegisterClass(BaseResourceComponent, 'AutotaggingPipelineResource')
], AutotaggingPipelineResourceComponent);
export { AutotaggingPipelineResourceComponent };
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AutotaggingPipelineResourceComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'app-autotagging-pipeline-resource', template: "<!-- Content Autotagging Pipeline Monitor -->\n<div class=\"autotagging-container\">\n    @if (IsLoading) {\n        <div class=\"loading-overlay\">\n            <mj-loading text=\"Loading pipeline data...\"></mj-loading>\n        </div>\n    }\n\n    @if (ErrorMessage) {\n        <div class=\"error-banner\">\n            <i class=\"fa-solid fa-triangle-exclamation\"></i>\n            <span>{{ ErrorMessage }}</span>\n            <button class=\"refresh-btn\" (click)=\"RefreshData()\">\n                <i class=\"fa-solid fa-rotate-right\"></i> Retry\n            </button>\n        </div>\n    }\n\n    @if (!IsLoading) {\n        <!-- Header -->\n        <div class=\"header-row\">\n            <div class=\"header-title\">\n                <i class=\"fa-solid fa-tags header-icon\"></i>\n                <h2>Content Autotagging Pipeline</h2>\n            </div>\n            <button class=\"refresh-btn\" (click)=\"RefreshData()\">\n                <i class=\"fa-solid fa-rotate-right\"></i> Refresh\n            </button>\n        </div>\n\n        <!-- KPI Strip -->\n        <div class=\"kpi-strip\">\n            @for (metric of KPIMetrics; track metric.Label) {\n                <div class=\"kpi-card\" [class]=\"metric.ColorClass\">\n                    <div class=\"kpi-icon\">\n                        <i [class]=\"metric.Icon\"></i>\n                    </div>\n                    <div class=\"kpi-content\">\n                        <span class=\"kpi-value\">{{ metric.Value | number }}</span>\n                        <span class=\"kpi-label\">{{ metric.Label }}</span>\n                    </div>\n                </div>\n            }\n        </div>\n\n        <!-- Pipeline Stages Visualization -->\n        <div class=\"pipeline-section\">\n            <h3 class=\"section-title\">\n                <i class=\"fa-solid fa-diagram-project\"></i> Pipeline Stages\n            </h3>\n            <div class=\"pipeline-flow\">\n                @for (stage of PipelineStages; track stage.Name; let last = $last) {\n                    <div class=\"pipeline-stage\" [class]=\"'stage-' + stage.Status\">\n                        <div class=\"stage-icon\">\n                            <i [class]=\"stage.Icon\"></i>\n                        </div>\n                        <span class=\"stage-name\">{{ stage.Name }}</span>\n                        <span class=\"stage-count\">\n                            @if (stage.ActiveCount > 0) {\n                                {{ stage.ActiveCount }} active\n                            } @else {\n                                Idle\n                            }\n                        </span>\n                        <div class=\"stage-indicator\"></div>\n                    </div>\n                    @if (!last) {\n                        <div class=\"stage-connector\">\n                            <i class=\"fa-solid fa-chevron-right\"></i>\n                        </div>\n                    }\n                }\n            </div>\n        </div>\n\n        <!-- Main content area: Feed + Sources sidebar -->\n        <div class=\"main-content\">\n            <!-- Recent Processing Feed -->\n            <div class=\"feed-section\">\n                <h3 class=\"section-title\">\n                    <i class=\"fa-solid fa-clock-rotate-left\"></i> Recent Processing\n                </h3>\n                <div class=\"feed-list\">\n                    @if (ProcessedItems.length === 0) {\n                        <div class=\"empty-state\">\n                            <i class=\"fa-solid fa-inbox\"></i>\n                            <p>No processed items yet.</p>\n                        </div>\n                    }\n                    @for (item of ProcessedItems; track $index) {\n                        <div class=\"feed-item\">\n                            <div class=\"feed-item-header\">\n                                <span class=\"feed-item-name\" [title]=\"item.Name\">{{ item.Name }}</span>\n                                <span class=\"feed-item-status\" [class]=\"GetStatusClass(item.Status)\">\n                                    {{ item.Status }}\n                                </span>\n                            </div>\n                            <div class=\"feed-item-details\">\n                                <span class=\"feed-detail\">\n                                    <i class=\"fa-solid fa-database\"></i> {{ item.SourceName }}\n                                </span>\n                                <span class=\"feed-detail\">\n                                    <i class=\"fa-solid fa-stopwatch\"></i> {{ FormatDuration(item.ProcessingTimeMs) }}\n                                </span>\n                                <span class=\"feed-detail\">\n                                    <i class=\"fa-solid fa-tags\"></i> {{ item.TagCount }} tags\n                                </span>\n                                <span class=\"feed-detail feed-time\">\n                                    {{ FormatRelativeTime(item.ProcessedAt) }}\n                                </span>\n                            </div>\n                        </div>\n                    }\n                </div>\n            </div>\n\n            <!-- Source Configuration Panel (right sidebar) -->\n            <div class=\"sources-panel\">\n                <h3 class=\"section-title\">\n                    <i class=\"fa-solid fa-gear\"></i> Content Sources\n                </h3>\n                <div class=\"sources-list\">\n                    @if (ContentSources.length === 0) {\n                        <div class=\"empty-state\">\n                            <i class=\"fa-solid fa-plug-circle-xmark\"></i>\n                            <p>No sources configured.</p>\n                        </div>\n                    }\n                    @for (source of ContentSources; track source.ID) {\n                        <div class=\"source-card\">\n                            <div class=\"source-header\">\n                                <div class=\"source-icon\">\n                                    <i [class]=\"source.TypeIcon\"></i>\n                                </div>\n                                <div class=\"source-info\">\n                                    <span class=\"source-name\">{{ source.Name }}</span>\n                                    <span class=\"source-type\">{{ source.TypeName }}</span>\n                                </div>\n                                <span class=\"source-status\" [class]=\"GetStatusClass(source.Status)\">\n                                    {{ source.Status }}\n                                </span>\n                            </div>\n                            <div class=\"source-meta\">\n                                <span class=\"source-meta-item\">\n                                    <i class=\"fa-solid fa-clock\"></i>\n                                    {{ FormatRelativeTime(source.LastRunAt) }}\n                                </span>\n                                <span class=\"source-meta-item\">\n                                    <i class=\"fa-solid fa-file-lines\"></i>\n                                    {{ source.ItemCount | number }} items\n                                </span>\n                            </div>\n                        </div>\n                    }\n                </div>\n            </div>\n        </div>\n    }\n</div>\n", styles: ["/* ============================================================\n   Content Autotagging Pipeline Monitor\n   All colors use MJ design tokens \u2014 no hardcoded hex values.\n   ============================================================ */\n\n:host {\n    display: block;\n    height: 100%;\n    overflow: hidden;\n}\n\n/* ---- Container ---- */\n\n.autotagging-container {\n    display: flex;\n    flex-direction: column;\n    height: 100%;\n    padding: 20px;\n    gap: 20px;\n    overflow-y: auto;\n    background: var(--mj-bg-page);\n    color: var(--mj-text-primary);\n}\n\n/* ---- Loading & Error ---- */\n\n.loading-overlay {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    height: 200px;\n}\n\n.error-banner {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    padding: 12px 16px;\n    border-radius: 6px;\n    background: var(--mj-status-error-bg);\n    color: var(--mj-status-error-text);\n    border: 1px solid var(--mj-status-error-border);\n}\n\n.error-banner i {\n    font-size: 16px;\n}\n\n.error-banner span {\n    flex: 1;\n}\n\n/* ---- Header ---- */\n\n.header-row {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n}\n\n.header-title {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n}\n\n.header-icon {\n    font-size: 20px;\n    color: var(--mj-brand-primary);\n}\n\n.header-title h2 {\n    margin: 0;\n    font-size: 20px;\n    font-weight: 600;\n    color: var(--mj-text-primary);\n}\n\n.refresh-btn {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    padding: 8px 14px;\n    border: 1px solid var(--mj-border-default);\n    border-radius: 6px;\n    background: var(--mj-bg-surface);\n    color: var(--mj-text-secondary);\n    cursor: pointer;\n    font-size: 13px;\n    transition: background 0.15s, border-color 0.15s;\n}\n\n.refresh-btn:hover {\n    background: var(--mj-bg-surface-hover);\n    border-color: var(--mj-border-strong);\n}\n\n/* ---- KPI Strip ---- */\n\n.kpi-strip {\n    display: grid;\n    grid-template-columns: repeat(4, 1fr);\n    gap: 16px;\n}\n\n.kpi-card {\n    display: flex;\n    align-items: center;\n    gap: 14px;\n    padding: 16px;\n    border-radius: 8px;\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-subtle);\n    transition: box-shadow 0.15s;\n}\n\n.kpi-card:hover {\n    box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.kpi-icon {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    width: 44px;\n    height: 44px;\n    border-radius: 10px;\n    font-size: 18px;\n    flex-shrink: 0;\n}\n\n.kpi-brand .kpi-icon {\n    background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n    color: var(--mj-brand-primary);\n}\n\n.kpi-info .kpi-icon {\n    background: color-mix(in srgb, var(--mj-status-info) 12%, var(--mj-bg-surface));\n    color: var(--mj-status-info);\n}\n\n.kpi-success .kpi-icon {\n    background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n    color: var(--mj-status-success);\n}\n\n.kpi-error .kpi-icon {\n    background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n    color: var(--mj-status-error);\n}\n\n.kpi-content {\n    display: flex;\n    flex-direction: column;\n}\n\n.kpi-value {\n    font-size: 22px;\n    font-weight: 700;\n    line-height: 1.2;\n    color: var(--mj-text-primary);\n}\n\n.kpi-label {\n    font-size: 12px;\n    color: var(--mj-text-muted);\n    text-transform: uppercase;\n    letter-spacing: 0.04em;\n}\n\n/* ---- Pipeline Stages ---- */\n\n.pipeline-section {\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-subtle);\n    border-radius: 8px;\n    padding: 18px 20px;\n}\n\n.section-title {\n    margin: 0 0 14px 0;\n    font-size: 14px;\n    font-weight: 600;\n    color: var(--mj-text-secondary);\n    display: flex;\n    align-items: center;\n    gap: 8px;\n}\n\n.section-title i {\n    color: var(--mj-text-muted);\n}\n\n.pipeline-flow {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 8px;\n    flex-wrap: wrap;\n}\n\n.pipeline-stage {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    gap: 6px;\n    padding: 14px 20px;\n    border-radius: 8px;\n    background: var(--mj-bg-surface-card);\n    border: 1px solid var(--mj-border-subtle);\n    min-width: 100px;\n    position: relative;\n    transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.stage-icon {\n    font-size: 20px;\n    color: var(--mj-text-muted);\n}\n\n.stage-name {\n    font-size: 13px;\n    font-weight: 600;\n    color: var(--mj-text-primary);\n}\n\n.stage-count {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n.stage-indicator {\n    position: absolute;\n    bottom: 0;\n    left: 10%;\n    right: 10%;\n    height: 3px;\n    border-radius: 3px 3px 0 0;\n    background: var(--mj-border-subtle);\n    transition: background 0.2s;\n}\n\n/* Stage status variants */\n\n.stage-active {\n    border-color: var(--mj-brand-primary);\n    box-shadow: 0 0 0 1px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.stage-active .stage-icon {\n    color: var(--mj-brand-primary);\n}\n\n.stage-active .stage-count {\n    color: var(--mj-brand-primary);\n    font-weight: 600;\n}\n\n.stage-active .stage-indicator {\n    background: var(--mj-brand-primary);\n}\n\n.stage-error {\n    border-color: var(--mj-status-error);\n}\n\n.stage-error .stage-icon {\n    color: var(--mj-status-error);\n}\n\n.stage-error .stage-indicator {\n    background: var(--mj-status-error);\n}\n\n.stage-connector {\n    display: flex;\n    align-items: center;\n    color: var(--mj-text-disabled);\n    font-size: 12px;\n}\n\n/* ---- Main Content Area (Feed + Sources) ---- */\n\n.main-content {\n    display: grid;\n    grid-template-columns: 1fr 320px;\n    gap: 20px;\n    flex: 1;\n    min-height: 0;\n}\n\n/* ---- Recent Processing Feed ---- */\n\n.feed-section {\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-subtle);\n    border-radius: 8px;\n    padding: 18px 20px;\n    display: flex;\n    flex-direction: column;\n    min-height: 0;\n}\n\n.feed-list {\n    flex: 1;\n    overflow-y: auto;\n    display: flex;\n    flex-direction: column;\n    gap: 2px;\n}\n\n.feed-item {\n    padding: 10px 12px;\n    border-radius: 6px;\n    transition: background 0.1s;\n}\n\n.feed-item:hover {\n    background: var(--mj-bg-surface-hover);\n}\n\n.feed-item-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 4px;\n}\n\n.feed-item-name {\n    font-size: 13px;\n    font-weight: 500;\n    color: var(--mj-text-primary);\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    max-width: 70%;\n}\n\n.feed-item-status {\n    font-size: 11px;\n    font-weight: 600;\n    padding: 2px 8px;\n    border-radius: 10px;\n    text-transform: uppercase;\n    letter-spacing: 0.03em;\n}\n\n.feed-item-details {\n    display: flex;\n    align-items: center;\n    gap: 14px;\n    flex-wrap: wrap;\n}\n\n.feed-detail {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n.feed-detail i {\n    font-size: 10px;\n}\n\n.feed-time {\n    margin-left: auto;\n}\n\n/* ---- Source Configuration Panel ---- */\n\n.sources-panel {\n    background: var(--mj-bg-surface);\n    border: 1px solid var(--mj-border-subtle);\n    border-radius: 8px;\n    padding: 18px 20px;\n    display: flex;\n    flex-direction: column;\n    min-height: 0;\n}\n\n.sources-list {\n    flex: 1;\n    overflow-y: auto;\n    display: flex;\n    flex-direction: column;\n    gap: 10px;\n}\n\n.source-card {\n    padding: 12px;\n    border-radius: 6px;\n    background: var(--mj-bg-surface-card);\n    border: 1px solid var(--mj-border-subtle);\n    transition: border-color 0.15s;\n}\n\n.source-card:hover {\n    border-color: var(--mj-border-default);\n}\n\n.source-header {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    margin-bottom: 8px;\n}\n\n.source-icon {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    width: 32px;\n    height: 32px;\n    border-radius: 6px;\n    background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n    color: var(--mj-brand-primary);\n    font-size: 14px;\n    flex-shrink: 0;\n}\n\n.source-info {\n    display: flex;\n    flex-direction: column;\n    flex: 1;\n    min-width: 0;\n}\n\n.source-name {\n    font-size: 13px;\n    font-weight: 600;\n    color: var(--mj-text-primary);\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n}\n\n.source-type {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n.source-status {\n    font-size: 11px;\n    font-weight: 600;\n    padding: 2px 8px;\n    border-radius: 10px;\n    text-transform: uppercase;\n    letter-spacing: 0.03em;\n    flex-shrink: 0;\n}\n\n.source-meta {\n    display: flex;\n    align-items: center;\n    gap: 14px;\n}\n\n.source-meta-item {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n.source-meta-item i {\n    font-size: 10px;\n}\n\n/* ---- Status Color Variants ---- */\n\n.status-success {\n    background: var(--mj-status-success-bg);\n    color: var(--mj-status-success-text);\n    border: 1px solid var(--mj-status-success-border);\n}\n\n.status-processing {\n    background: var(--mj-status-info-bg);\n    color: var(--mj-status-info-text);\n    border: 1px solid var(--mj-status-info-border);\n}\n\n.status-error {\n    background: var(--mj-status-error-bg);\n    color: var(--mj-status-error-text);\n    border: 1px solid var(--mj-status-error-border);\n}\n\n.status-warning {\n    background: var(--mj-status-warning-bg);\n    color: var(--mj-status-warning-text);\n    border: 1px solid var(--mj-status-warning-border);\n}\n\n.status-default {\n    background: var(--mj-bg-surface-sunken);\n    color: var(--mj-text-muted);\n    border: 1px solid var(--mj-border-subtle);\n}\n\n/* ---- Empty State ---- */\n\n.empty-state {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    gap: 8px;\n    padding: 32px 16px;\n    color: var(--mj-text-disabled);\n}\n\n.empty-state i {\n    font-size: 28px;\n}\n\n.empty-state p {\n    margin: 0;\n    font-size: 13px;\n}\n\n/* ---- Responsive ---- */\n\n@media (max-width: 1100px) {\n    .main-content {\n        grid-template-columns: 1fr;\n    }\n}\n\n@media (max-width: 768px) {\n    .kpi-strip {\n        grid-template-columns: repeat(2, 1fr);\n    }\n\n    .pipeline-flow {\n        gap: 6px;\n    }\n\n    .pipeline-stage {\n        min-width: 80px;\n        padding: 10px 12px;\n    }\n}\n\n@media (max-width: 480px) {\n    .kpi-strip {\n        grid-template-columns: 1fr;\n    }\n\n    .pipeline-stage {\n        min-width: 70px;\n    }\n\n    .header-row {\n        flex-direction: column;\n        align-items: flex-start;\n        gap: 10px;\n    }\n}\n"] }]
    }], null, null); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AutotaggingPipelineResourceComponent, { className: "AutotaggingPipelineResourceComponent", filePath: "src/AI/components/autotagging/autotagging-pipeline-resource.component.ts", lineNumber: 60 }); })();
export function LoadAutotaggingPipelineResource() {
    // Prevents tree-shaking
}
//# sourceMappingURL=autotagging-pipeline-resource.component.js.map