import { __decorate, __metadata } from "tslib";
import { Component, ChangeDetectionStrategy, ChangeDetectorRef, Inject, Optional, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DynamicItemLoader, PackageManager } from '@anglr/dynamic';
import { FirstUppercaseLocalizeSAPipe, LOGGER } from '@anglr/common';
import { DebounceCall, nameof, WithSync } from '@jscrpt/common';
import { Subscription } from 'rxjs';
import { LayoutEditorMetadataExtractor } from '../../services';
import { ToLayoutDragDataSAPipe } from '../../pipes';
import { LAYOUT_MODULE_TYPES_LOADER, REFRESH_PALETTE_OBSERVABLES } from '../../misc/tokens';
import { LayoutDndCoreModule } from '../../modules';
import * as i0 from "@angular/core";
import * as i1 from "@anglr/dynamic";
import * as i2 from "../../services";
import * as i3 from "@angular/common";
import * as i4 from "../../modules/layoutDndCore/directives/dndCorePaletteItem/dndCorePaletteItem.directive";
/**
 * Component displaying available components palette
 */
export class ComponentsPaletteSAComponent {
    /**
     * Gets array of used packages
     */
    get usedPackages() {
        return this.packages ?? this.packageManager.usedPackages;
    }
    //######################### constructor #########################
    constructor(moduleTypesLoader, changeDetector, packageManager, metadataExtractor, _refreshObservables, logger) {
        this.moduleTypesLoader = moduleTypesLoader;
        this.changeDetector = changeDetector;
        this.packageManager = packageManager;
        this.metadataExtractor = metadataExtractor;
        this._refreshObservables = _refreshObservables;
        this.logger = logger;
        //######################### protected properties #########################
        /**
         * Subscriptions created during initialization
         */
        this.initSubscriptions = new Subscription();
        /**
         * Array of all available items in palette
         */
        this.allItems = [];
        /**
         * Array of whitelisted packages
         */
        this.whiteListedPackages = [];
        //######################### protected properties - template bindings #########################
        /**
         * Available items grouped by group name
         */
        this.groupedItems = {};
        /**
         * Used for refreshing pipe value
         */
        this.refreshPipe = false;
    }
    //######################### public methods - implementation of OnInit #########################
    /**
     * Initialize component
     */
    async ngOnInit() {
        this.initSubscriptions.add(this.packageManager.usedPackagesChange.subscribe(() => this.initItems()));
        if (this._refreshObservables && Array.isArray(this._refreshObservables)) {
            for (const obs of this._refreshObservables) {
                this.initSubscriptions.add(obs.subscribe(() => this.initItems()));
            }
        }
        await this.initItems();
    }
    //######################### public methods - implementation of OnChanges #########################
    /**
     * Called when input value changes
     */
    async ngOnChanges(changes) {
        if (nameof('whiteList') in changes) {
            this.whiteListedPackages = [];
            if (Array.isArray(this.whiteList)) {
                for (const source of this.whiteList) {
                    //package already whitelisted
                    if (this.whiteListedPackages.find(itm => itm == source.package)) {
                        continue;
                    }
                    this.whiteListedPackages.push(source.package);
                }
            }
        }
        if (nameof('whiteList') in changes ||
            nameof('blackList') in changes ||
            nameof('packages') in changes) {
            await this.initItems();
        }
    }
    //######################### public methods - implementation of OnDestroy #########################
    /**
     * Called when component is destroyed
     */
    ngOnDestroy() {
        this.initSubscriptions.unsubscribe();
    }
    //######################### protected methods #########################
    /**
     * Initialize items in palette
     */
    async initItems() {
        var _a;
        this.groupedItems = {};
        this.allItems = [];
        for (const packageName of this.usedPackages) {
            const types = (await this.moduleTypesLoader.loadItem({ package: packageName, name: 'types' }))?.data ?? [];
            for (const type of types) {
                //package is whitelisted
                if (this.whiteListedPackages.find(itm => packageName == itm)) {
                    //item is not whitelisted
                    if (!this.whiteList?.find(itm => itm.package == packageName && itm.name == type)) {
                        continue;
                    }
                }
                //item is blacklisted
                else if (this.blackList?.find(itm => itm.package == packageName && itm.name == type)) {
                    continue;
                }
                const itemSource = { package: packageName, name: type };
                const metadata = await this.metadataExtractor.extractMetadata(itemSource);
                if (!metadata) {
                    this.logger?.warn('ComponentsPaletteSAComponent: Failed to obtain layout editor metadata {{@source}}', { source: itemSource });
                }
                else {
                    this.allItems.push({
                        itemSource,
                        metadata
                    });
                }
            }
        }
        this.groupedItems[''] = [];
        //group items
        for (const item of this.allItems) {
            const group = item.metadata.metaInfo?.group ?? '';
            (_a = this.groupedItems)[group] ?? (_a[group] = []);
            this.groupedItems[group].push(item);
        }
        this.changeDetector.detectChanges();
    }
}
ComponentsPaletteSAComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: ComponentsPaletteSAComponent, deps: [{ token: LAYOUT_MODULE_TYPES_LOADER }, { token: i0.ChangeDetectorRef }, { token: i1.PackageManager }, { token: i2.LayoutEditorMetadataExtractor }, { token: REFRESH_PALETTE_OBSERVABLES, optional: true }, { token: LOGGER, optional: true }], target: i0.ɵɵFactoryTarget.Component });
ComponentsPaletteSAComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.4", type: ComponentsPaletteSAComponent, isStandalone: true, selector: "components-palette", inputs: { packages: "packages", whiteList: "whiteList", blackList: "blackList" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"dynamic-flex-column\">\n    <ng-container *ngFor=\"let groupKeyValue of groupedItems | keyvalue\">\n        <div class=\"dynamic-text-spread dynamic-text-small-caps dynamic-margin-left-extra-small dynamic-margin-horizontal-small dynamic-bold\">{{groupKeyValue.key|firstUppercaseLocalize}}&nbsp;</div>\n\n        <div *ngFor=\"let item of groupKeyValue.value\"\n             class=\"palette-droplist\">\n            <div class=\"editor-component mat-elevation-z2\"\n                 [dndCorePaletteItem]=\"item | toLayoutDragData\"\n                 (itemDrop)=\"refreshPipe = !refreshPipe\">\n                <div class=\"editor-component-name\">{{item.metadata.metaInfo?.name ?? item.itemSource.name|firstUppercaseLocalize}}</div>\n                <div class=\"editor-component-description\" *ngIf=\"item.metadata.metaInfo?.description\">{{item.metadata.metaInfo?.description|firstUppercaseLocalize}}</div>\n            </div>\n        </div>\n    </ng-container>\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: LayoutDndCoreModule }, { kind: "directive", type: i4.DndCorePaletteItemDirective, selector: "[dndCorePaletteItem]", inputs: ["dndCorePaletteItem"], outputs: ["itemDrop"] }, { kind: "pipe", type: ToLayoutDragDataSAPipe, name: "toLayoutDragData" }, { kind: "pipe", type: FirstUppercaseLocalizeSAPipe, name: "firstUppercaseLocalize" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
__decorate([
    DebounceCall(10),
    WithSync(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], ComponentsPaletteSAComponent.prototype, "initItems", null);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: ComponentsPaletteSAComponent, decorators: [{
            type: Component,
            args: [{ selector: 'components-palette', standalone: true, imports: [
                        CommonModule,
                        LayoutDndCoreModule,
                        ToLayoutDragDataSAPipe,
                        FirstUppercaseLocalizeSAPipe,
                    ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"dynamic-flex-column\">\n    <ng-container *ngFor=\"let groupKeyValue of groupedItems | keyvalue\">\n        <div class=\"dynamic-text-spread dynamic-text-small-caps dynamic-margin-left-extra-small dynamic-margin-horizontal-small dynamic-bold\">{{groupKeyValue.key|firstUppercaseLocalize}}&nbsp;</div>\n\n        <div *ngFor=\"let item of groupKeyValue.value\"\n             class=\"palette-droplist\">\n            <div class=\"editor-component mat-elevation-z2\"\n                 [dndCorePaletteItem]=\"item | toLayoutDragData\"\n                 (itemDrop)=\"refreshPipe = !refreshPipe\">\n                <div class=\"editor-component-name\">{{item.metadata.metaInfo?.name ?? item.itemSource.name|firstUppercaseLocalize}}</div>\n                <div class=\"editor-component-description\" *ngIf=\"item.metadata.metaInfo?.description\">{{item.metadata.metaInfo?.description|firstUppercaseLocalize}}</div>\n            </div>\n        </div>\n    </ng-container>\n</div>" }]
        }], ctorParameters: () => [{ type: i1.DynamicItemLoader, decorators: [{
                    type: Inject,
                    args: [LAYOUT_MODULE_TYPES_LOADER]
                }] }, { type: i0.ChangeDetectorRef }, { type: i1.PackageManager }, { type: i2.LayoutEditorMetadataExtractor }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [REFRESH_PALETTE_OBSERVABLES]
                }, {
                    type: Optional
                }] }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [LOGGER]
                }, {
                    type: Optional
                }] }], propDecorators: { packages: [{
                type: Input
            }], whiteList: [{
                type: Input
            }], blackList: [{
                type: Input
            }], initItems: [] } });
//# sourceMappingURL=componentsPalette.component.js.map