import * as i0 from '@angular/core';
import { EventEmitter, Component, Input, Output, ViewChild, NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import * as i5 from '@laserfiche/lf-ui-components/lf-selection-list';
import { LfSelectionListComponent, LfSelectionListModule } from '@laserfiche/lf-ui-components/lf-selection-list';
import * as i1 from '@angular/material/dialog';
import * as i2 from '@laserfiche/lf-ui-components/internal-shared';
import { LfLoaderModule } from '@laserfiche/lf-ui-components/internal-shared';
import * as i3 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i4 from '@laserfiche/lf-ui-components/shared';
import { LfBreadcrumbsModule } from '@laserfiche/lf-ui-components/shared';
import { createCustomElement } from '@angular/elements';
import { FormsModule } from '@angular/forms';

// Copyright (c) Laserfiche.
// Licensed under the MIT License. See LICENSE in the project root for license information.
/** @internal */
const NAME_COL_AUTO = {
    id: 'name',
    displayName: 'Name',
    defaultWidth: 'auto',
    minWidthPx: 100,
    resizable: true,
    sortable: true,
};
/** @internal */
const NAME_COL_50CH = {
    id: 'name',
    displayName: 'Name',
    defaultWidth: '50ch',
    minWidthPx: 100,
    resizable: true,
    sortable: true,
};
class LfRepositoryBrowserComponent {
    /**
     * read-only property to get current breadcrumbs
     */
    get breadcrumbs() {
        return this._breadcrumbs;
    }
    /**
     * read-only property to retrieve currently opened LfTreeNode
     */
    get currentFolder() {
        return this._currentFolder;
    }
    /**
     * Property to set height in pixels of each item in lf-repository-browser
     */
    set item_size(value) {
        if (typeof value === 'string') {
            value = parseInt(value, 10);
        }
        this._itemSize = value;
    }
    get item_size() {
        return this._itemSize;
    }
    /**
     * Property to set number of items rendered, should be set to more than the number of visible nodes
     */
    set page_size(value) {
        if (typeof value === 'string') {
            value = parseInt(value, 10);
        }
        this._pageSize = value;
    }
    get page_size() {
        return this._pageSize;
    }
    /**
     * Property to get and set the current column to order by
     */
    get column_order_by() {
        return this.entryList?.columnOrderBy;
    }
    set column_order_by(orderBy) {
        if (this.entryList) {
            this.entryList.columnOrderBy = orderBy;
        }
    }
    /**
     * Property to set whether or not to always show header. By default will only show header if there is more than one column
     */
    set always_show_header(showHeader) {
        if (typeof showHeader === 'string') {
            if (showHeader.toLowerCase() === 'true') {
                showHeader = true;
            }
            else {
                showHeader = false;
            }
        }
        if (this.entryList) {
            this.entryList.alwaysShowHeader = showHeader;
        }
    }
    /**
     * Property to get and set whether multiple select is enabled on the component
     */
    set multiple(value) {
        if (typeof value === 'string') {
            if (value.toLowerCase() === 'true') {
                value = true;
            }
            else {
                value = false;
            }
        }
        this._multipleSelectEnabled = value;
    }
    get multiple() {
        return this._multipleSelectEnabled;
    }
    /** @internal */
    get shouldShowErrorMessage() {
        return this.hasError;
    }
    /** @internal */
    get shouldShowEmptyMessage() {
        return this.currentFolderChildren.length === 0 && !this.hasError;
    }
    /** @internal */
    constructor(
    /** @internal */
    ref, 
    /** @internal */
    popupDialog, 
    /** @internal */
    zone, 
    /** @internal */
    localizationService, 
    /** @internal */
    el) {
        this.ref = ref;
        this.popupDialog = popupDialog;
        this.zone = zone;
        this.localizationService = localizationService;
        this.el = el;
        /**
         * Function to set additional columns to display. You can use this to set a specific name column as well, or accept the default.
         */
        this.setColumnsToDisplay = (cols) => {
            if (this.entryList) {
                const nameColumnDef = cols.find((col) => col.id === 'name');
                if (!nameColumnDef) {
                    let nameCol;
                    if (!cols || cols.length === 0) {
                        nameCol = NAME_COL_AUTO;
                    }
                    else {
                        nameCol = NAME_COL_50CH;
                    }
                    cols.unshift(nameCol);
                }
                this.entryList.columns = cols;
            }
            this.ref.detectChanges();
        };
        /**
         * Function to initialize the lf-repository-browser component
         * @param treeNodeService LfRepositoryService service
         * @param initialOpenedNode The LfTreeNode that you would like to open, or the identifier of the LfTreeNode. The identifier should match the implementation of service.getTreeNodeByIdentifierAsync(..) (i.e. id, path, etc.)
         */
        this.initAsync = async (treeNodeService, initialOpenedNode) => {
            await this.zone.run(async () => {
                try {
                    this.hasError = false;
                    this.isLoading = true;
                    this.treeNodeService = treeNodeService;
                    if (typeof initialOpenedNode === 'string') {
                        if (!initialOpenedNode || initialOpenedNode.trim().length === 0) {
                            initialOpenedNode = undefined;
                        }
                        else {
                            if (this.treeNodeService.getTreeNodeByIdentifierAsync) {
                                try {
                                    initialOpenedNode = await this.treeNodeService.getTreeNodeByIdentifierAsync(initialOpenedNode);
                                }
                                catch {
                                    console.warn('Unable to determine LfTreeNode by id. Will initialize to root.');
                                    initialOpenedNode = undefined;
                                }
                            }
                            else {
                                console.warn('initialOpenedNode is specified by an id, but getTreeNodeByIdentifierAsync is not implemented. Will initialize to root.');
                                initialOpenedNode = undefined;
                            }
                        }
                    }
                    await this.initializeAsync(initialOpenedNode);
                }
                catch (error) {
                    console.error(error);
                    this.hasError = true;
                }
                finally {
                    this.isLoading = false;
                    this.ref.detectChanges();
                }
            });
        };
        /**
         * Function to set selectedNodes. If current data does not include all the requested node, it will call getFolderChildren until there are no more, or maxFetchIterations is reached.
         * @param nodesToSelect array of LfTreeNodes to select by id
         * @param maxFetchIterations Max number of times to get data if the current data doesn't contain all of the requested nodes. Default is 5.
         * @returns void
         */
        this.setSelectedNodesAsync = async (nodesToSelect, maxFetchIterations = 5) => {
            const selectableValues = await this.mapTreeNodesToLfSelectableAsync(nodesToSelect);
            if (!this.entryList && this.isLoading) {
                setTimeout(() => {
                    this.setSelectedNodesAsync(nodesToSelect, maxFetchIterations);
                });
                return;
            }
            if (this.entryList) {
                this.entryList.clearSelectedValues();
                const selectedNodes = await this.entryList.setSelectedNodesAsync(selectableValues, this.checkForMoreDataCallback.bind(this), maxFetchIterations);
                const selectedItems = this.convertSelectedItemsToTreeNode(selectedNodes);
                if ((selectedItems?.length === 0 && this.selectedItems?.length === 0) ||
                    JSON.stringify(selectedItems) === JSON.stringify(this.selectedItems)) {
                    // do nothing
                }
                else {
                    this.selectedItems = selectedItems;
                    this.entrySelected.emit(this.selectedItems);
                }
            }
        };
        /**
         * Function to refresh data in folder (get first page)
         * @param clearSelectedValues Optional parameter to clear all the currently selected values. Default is true.
         */
        this.refreshAsync = async (clearSelectedValues = true) => {
            try {
                this.hasError = false;
                this.isLoading = true;
                if (!this._currentFolder) {
                    this._currentFolder = await this.treeNodeService.getRootTreeNodeAsync();
                }
                if (!this._currentFolder) {
                    throw new Error('No root was found, repository browser was unable to refresh.');
                }
                this.nextPage = undefined;
                this.lastCalledPage = undefined;
                this.maximumChildrenReceived = false;
                this.currentFolderChildren = [];
                this.ref.detectChanges();
                await this.updateAllPossibleEntriesAsync(this._currentFolder, clearSelectedValues);
                await this.initializeBreadcrumbOptionsAsync(this._currentFolder);
            }
            catch {
                this.hasError = true;
            }
            finally {
                this.isLoading = false;
                this.ref.detectChanges();
            }
        };
        /**
         * Function to open selected node(s). If there is just one container node it will open the container in the UI and emit the entryDblClicked event,
         * if there is more than one node or it is not a container, it will just emit the entryDblClicked event
         */
        this.openSelectedNodesAsync = async () => {
            if (this.selectedItems && this.selectedItems.length > 0) {
                await this.openSelectedItemsAsync();
            }
            else {
                console.debug('No selected nodes to open');
            }
        };
        /**
         * Function to open focused node. If there is just one container node it will open the container in the UI and emit the entryDblClicked event
         */
        this.openFocusedNodeAsync = async () => {
            if (this.focusedEntry) {
                const nodeToOpen = this.focusedEntry;
                await this.openChildFolderAsync(nodeToOpen);
                this.entryDblClicked.emit([nodeToOpen]);
            }
            else {
                console.debug('No focused node to open');
            }
        };
        /**
         * Focuses the first item in the repository browser list
         * TODO: Add an optional parameter to allow for focusing a specific node
         */
        this.focus = () => {
            this._focus();
        };
        /** Event triggered on double click (open) of a node. This can be accompanied by the UI opening a single container */
        this.entryDblClicked = new EventEmitter();
        /** Event triggered on selection (click/space bar) of a node.*/
        this.entrySelected = new EventEmitter();
        /** Event triggered on focus of a node.*/
        this.entryFocused = new EventEmitter();
        /** @internal */
        this._multipleSelectEnabled = false;
        /** @internal */
        this._pageSize = 50;
        /** @internal */
        this._itemSize = 42;
        /** @internal */
        this.repoBrowserUniqueId = '';
        /** @internal */
        this.currentFolderChildren = [];
        /** @internal */
        this.hasError = false;
        /** @internal */
        this.isLoading = true;
        /**
         * @internal
         * TODO: Add a message for when the repository browser is not initialized
         * When that happens default isLoading to false
         */
        this.initialized = false;
        /** @internal */
        this.AN_ERROR_OCCURED = this.localizationService.getStringLaserficheObservable('AN_ERROR_OCCURED');
        /** @internal */
        this.THIS_FOLDER_IS_EMPTY = this.localizationService.getStringLaserficheObservable('THIS_FOLDER_IS_EMPTY');
        /** @internal */
        this.maximumChildrenReceived = false;
        /** @internal */
        this._breadcrumbs = [];
        /** @internal */
        this.scrolledIndexChanged = new Subject();
        this.scrolledIndexChanged.pipe(debounceTime(200)).subscribe(async () => {
            if (!this._currentFolder) {
                return;
            }
            if (!this.maximumChildrenReceived) {
                if (this.nextPage && this.nextPage == this.lastCalledPage) {
                    // do nothing. nextPage already attempted
                    return;
                }
                await this.makeDataCall(this._currentFolder);
                this.ref.detectChanges();
                this.resetSelectedItemsAsync();
            }
        });
    }
    /** @internal */
    ngAfterViewInit() {
        const path = window.location.pathname;
        this.repoBrowserUniqueId = `lf-repository-browser_${path}_${this.el.nativeElement.id}`;
        this.ref.detectChanges();
    }
    /**
     * @internal
     * Handles when a bread crumb is clicked
     * @param event
     * @returns
     */
    async onBreadcrumbClicked(event) {
        if (!event.breadcrumbs || !event.selected) {
            console.error('onBreadcrumbClicked event is required to have a breadcrumbs as well as a selected entry');
            return;
        }
        this._breadcrumbs = event.breadcrumbs;
        this._currentFolder = event.selected;
        await this.updateAllPossibleEntriesAsync(this._currentFolder);
        this.entryDblClicked.emit([this._currentFolder]);
        setTimeout(() => this.entryList?.focus());
    }
    /**
     * @internal
     * @param entry
     * @returns list of strings that represent img src's
     */
    getIcons(entry) {
        return typeof entry.icon === 'string' ? [entry.icon] : entry.icon;
    }
    /**
     * @internal
     * Handles when a entry in the repository browser is double clicked
     * @param entry
     * @returns
     */
    async onDblClickAsync(treeNode) {
        await this.openChildFolderAsync(treeNode);
        this.entryDblClicked.emit([treeNode]);
    }
    /**
     * @internal
     * Handles the scrolling event from the lf-selection-list
     */
    onScroll() {
        this.scrolledIndexChanged.next();
    }
    /**
     * @internal
     * Handles the SelectedItemEvent from the lf-selection-list
     * @param event
     */
    async onItemSelected(event) {
        const lastSelectedItem = this.selectedItems && this.selectedItems.length > 0
            ? this.selectedItems[this.selectedItems.length - 1]
            : undefined;
        if ((lastSelectedItem &&
            lastSelectedItem === event.selected.value &&
            this.selectedItems?.length === event.selectedItems?.length) ||
            (event.selectedItems?.length === 0 && this.selectedItems?.length === 0)) {
            // do nothing
            return;
        }
        this.selectedItems = event.selectedItems?.map((item) => item.value);
        this.entrySelected.emit(this.selectedItems);
    }
    /** @internal */
    onEntryFocused(item) {
        this.focusedEntry = item;
        this.entryFocused.emit(item ? item : undefined);
    }
    /**
     * @internal
     * Opens the entry passed as the parameter
     * Example: This will get called when an entry is double clicked
     * @param entry
     */
    async openChildFolderAsync(entry) {
        if (!entry?.isContainer) {
            return;
        }
        this._currentFolder = entry;
        await this.updateAllPossibleEntriesAsync(entry);
        this._breadcrumbs = [entry].concat(this.breadcrumbs);
        this._focus();
    }
    /**
     * @internal
     */
    async openSelectedItemsAsync() {
        const selectedNodes = this.selectedItems;
        if (selectedNodes?.length === 1 && selectedNodes[0].isContainer) {
            await this.openChildFolderAsync(selectedNodes[0]);
        }
        this.entryDblClicked.emit(selectedNodes);
    }
    /**
     * @internal
     * Callback that is passed to the lf-selection-list so it can continue to get more data if needed to select
     * initial values
     * @returns
     */
    async checkForMoreDataCallback() {
        if (!this._currentFolder) {
            return;
        }
        if (!this.maximumChildrenReceived) {
            const data = await this.makeDataCall(this._currentFolder);
            return data;
        }
        return;
    }
    /**
     * @internal
     * Maps ILfSelectable list to a TreeNode list
     * @param selected
     * @returns
     */
    convertSelectedItemsToTreeNode(selected) {
        return selected.map((value) => value.value);
    }
    /**
     * @internal
     * Attempts to focus the entryList component
     * @param node Not used right now but is part of the TODO for focus fuction
     * @param tries
     */
    _focus(node = undefined, tries = 0) {
        if (tries >= 10) {
            return;
        }
        if (!this.entryList) {
            setTimeout(() => this._focus(node, tries + 1));
            return;
        }
        if (this.shouldShowEmptyMessage || this.shouldShowErrorMessage) {
            setTimeout(() => {
                document.querySelector(".lf-repo-entry-container")?.focus();
            });
        }
        else {
            this.entryList?.focus();
        }
    }
    /**
     * @internal
     * Attempts to initialize the repository browser
     * Will initialize with the root node if not currentIdOrEntry is provided
     * Otherwise will use the provided entry to build the breadcrumbs and pull the corresponding data
     * @param currentIdOrEntry
     * @returns
     */
    async initializeAsync(currentEntry) {
        if (!this.treeNodeService) {
            this.hasError = true;
            throw new Error('Repository Browser cannot be initialized without a data service.');
        }
        if (!currentEntry) {
            currentEntry = await this.treeNodeService.getRootTreeNodeAsync();
        }
        // If the entry passed in is not a container we will get the parent of this by default.
        if (currentEntry && !currentEntry.isContainer) {
            currentEntry = await this.treeNodeService.getParentTreeNodeAsync(currentEntry);
        }
        if (!currentEntry) {
            throw new Error('currentEntry is undefined');
        }
        this.initialized = true;
        await this.setNodeAsParentAsync(currentEntry);
        this.setColumnsToDisplay(this.entryList?.columns ?? []);
    }
    /**
     * @internal
     * Uses the entry passed in to build the breadcrumbs
     * @param selectedEntry
     * @returns
     */
    async initializeBreadcrumbOptionsAsync(selectedEntry) {
        this._breadcrumbs = [selectedEntry];
        let currentNode = selectedEntry;
        while (currentNode) {
            const nextParent = await this.treeNodeService.getParentTreeNodeAsync(currentNode);
            if (nextParent) {
                this.breadcrumbs.push(nextParent);
            }
            currentNode = nextParent;
        }
    }
    /**
     * @internal
     * Maps TreeNode list to ILfSelectable items for use in the entryList
     * @param nodes
     * @returns
     */
    async mapTreeNodesToLfSelectableAsync(nodes) {
        const selectablePage = [];
        for (const value of nodes) {
            const selectableValue = {
                value,
                isSelectable: this.isSelectable ? await this.isSelectable(value) : true,
                isSelected: false,
            };
            selectablePage.push(selectableValue);
        }
        return selectablePage;
    }
    /**
     * @internal
     * Resets the errors, selected values, currentFolderChildren and nextPage
     */
    resetFolderProperties(clearCache) {
        this.hasError = false;
        this.entryList?.clearSelectedValues(clearCache);
        this.currentFolderChildren = [];
        this.ref.detectChanges();
        //this._focused_node = undefined;
        this.nextPage = undefined;
        this.lastCalledPage = undefined;
        this.maximumChildrenReceived = false;
    }
    /**
     * @internal
     * Makes the parentEntry parameter into the current parent node
     * Will setup the breadcrumbs to be the listOfAncestorEntries with the parentEntry as the last one if passed in
     * @param parentEntry
     * @param listOfAncestorEntries
     * @returns
     */
    async setNodeAsParentAsync(parentEntry) {
        if (!parentEntry) {
            console.error('parentEntry must not be null');
            return;
        }
        if (!parentEntry.isContainer) {
            console.error('parentEntry must be a container');
            return;
        }
        await this.initializeBreadcrumbOptionsAsync(parentEntry);
        this._currentFolder = parentEntry;
        await this.updateAllPossibleEntriesAsync(parentEntry);
    }
    /**
     * @internal
     * Resets the list and pulls new data for the parentEntry
     * @param parentEntry
     * @param refresh Not Used currently
     */
    async updateAllPossibleEntriesAsync(parentEntry, clearSelected = true) {
        // If we are already getting data we want to wait for that to finish before resetting and pulling new data.
        if (this.lastDataCall) {
            // If we get an error in the last data call just throw it away.
            await this.lastDataCall.catch((error) => undefined);
        }
        if (parentEntry && parentEntry.id) {
            try {
                await this.refreshTreeNodeAsync(parentEntry);
                const lastSelectedItems = this.selectedItems;
                this.isLoading = true;
                this.hasError = false;
                this.resetFolderProperties(clearSelected);
                await this.makeDataCall(parentEntry);
                this.isLoading = false;
                this.ref.detectChanges();
                if (!clearSelected) {
                    this.selectedItems = await this.resetSelectedItemsAsync();
                }
                else {
                    this.selectedItems = [];
                }
                if ((lastSelectedItems?.length === 0 && this.selectedItems?.length === 0) ||
                    JSON.stringify(lastSelectedItems) === JSON.stringify(this.selectedItems)) {
                    // do nothing
                }
                else {
                    this.entrySelected.emit(this.selectedItems);
                }
            }
            catch (error) {
                console.error(error);
                this.lastDataCall = undefined;
                this.hasError = true;
            }
            finally {
                this.isLoading = false;
                this.ref.detectChanges();
            }
        }
        else {
            console.error('updateAllPossibleEntriesAsync parentEntry undefined or missing id property');
            this.hasError = true;
        }
    }
    /** @internal */
    async refreshTreeNodeAsync(entry) {
        try {
            if (this.treeNodeService.getTreeNodeByIdentifierAsync) {
                var refreshedTreeNode = await this.treeNodeService.getTreeNodeByIdentifierAsync(entry.id);
                if (refreshedTreeNode) {
                    Object.assign(entry, refreshedTreeNode);
                }
            }
        }
        catch (error) {
            console.error(`refreshTreeNodeNameAsync failed with error: ${error}`);
        }
    }
    /** @internal */
    async resetSelectedItemsAsync() {
        const resetSelectedNodes = await this.entryList.resetCachedNodesAsync();
        const selectedItems = this.convertSelectedItemsToTreeNode(resetSelectedNodes);
        return selectedItems;
    }
    /** @internal */
    async makeDataCall(parentEntry) {
        try {
            this.hasError = false;
            const selectable = [];
            while (!this.maximumChildrenReceived && selectable.length < this.page_size) {
                this.lastDataCall = this.updateFolderChildrenAsync(parentEntry);
                const additionalData = await this.lastDataCall;
                selectable.push(...additionalData);
                this.lastDataCall = undefined;
            }
            this.currentFolderChildren = this.currentFolderChildren.concat(...selectable);
            return selectable;
        }
        catch (error) {
            this.hasError = true;
            this.isLoading = false;
            this.ref.detectChanges();
            return undefined;
        }
    }
    /**
     * @internal
     * Does the work to call the treeNodeService and map the returned values to ILfSelectable entries
     * @param parentEntry
     * @returns
     */
    async updateFolderChildrenAsync(parentEntry) {
        this.lastCalledPage = this.nextPage;
        const sortState = this.column_order_by;
        const dataPage = await this.treeNodeService.getFolderChildrenAsync(parentEntry, this.nextPage, sortState);
        this.nextPage = dataPage.nextPage;
        const pageTreeNodes = dataPage.page;
        const selectablePage = await this.mapTreeNodesToLfSelectableAsync(pageTreeNodes);
        if (this.nextPage) {
            this.maximumChildrenReceived = false;
        }
        else {
            this.maximumChildrenReceived = true;
        }
        return selectablePage;
    }
    /** @internal */
    ngOnDestroy() {
        this.scrolledIndexChanged.unsubscribe();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LfRepositoryBrowserComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.MatDialog }, { token: i0.NgZone }, { token: i2.AppLocalizationService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: LfRepositoryBrowserComponent, selector: "lf-repository-browser-component", inputs: { breadcrumbs: "breadcrumbs", currentFolder: "currentFolder", item_size: "item_size", page_size: "page_size", column_order_by: "column_order_by", always_show_header: "always_show_header", setColumnsToDisplay: "setColumnsToDisplay", initAsync: "initAsync", isSelectable: "isSelectable", multiple: "multiple", setSelectedNodesAsync: "setSelectedNodesAsync", refreshAsync: "refreshAsync", openSelectedNodesAsync: "openSelectedNodesAsync", openFocusedNodeAsync: "openFocusedNodeAsync", focus: "focus" }, outputs: { entryDblClicked: "entryDblClicked", entrySelected: "entrySelected", entryFocused: "entryFocused" }, viewQueries: [{ propertyName: "entryList", first: true, predicate: LfSelectionListComponent, descendants: true }], ngImport: i0, template: "<!--Copyright (c) Laserfiche.\r\nLicensed under the MIT License. See LICENSE in the project root for license information.-->\r\n\r\n<div class=\"lf-repository-browser-header\">\r\n  <lf-breadcrumbs-component [breadcrumbs]=\"breadcrumbs\" (breadcrumbClicked)=\"onBreadcrumbClicked($event)\">\r\n  </lf-breadcrumbs-component>\r\n  <ng-content select=\"lf-toolbar\"></ng-content>\r\n</div>\r\n<div class=\"lf-repo-entry-container\" [attr.tabindex]=\"isLoading || shouldShowErrorMessage || shouldShowEmptyMessage ? 0 : -1\">\r\n  <lf-loader-component *ngIf=\"isLoading\" class=\"lf-text-body lf-no-user-select\"></lf-loader-component>\r\n  <div id=\"message-display\" *ngIf=\"!isLoading && (shouldShowErrorMessage || shouldShowEmptyMessage)\">\r\n    <div *ngIf=\"shouldShowErrorMessage\" class=\"lf-text-body lf-text-error lf-no-user-select\">{{ AN_ERROR_OCCURED | async }}</div>\r\n    <div *ngIf=\"shouldShowEmptyMessage\" class=\"lf-text-body lf-no-user-select\">{{ THIS_FOLDER_IS_EMPTY | async }}</div>\r\n  </div>\r\n\r\n  <lf-selection-list-component\r\n    [hidden]=\"isLoading || shouldShowErrorMessage || shouldShowEmptyMessage\"\r\n    [uniqueIdentifier]=\"repoBrowserUniqueId\"\r\n    [listItems]=\"currentFolderChildren\"\r\n    [multipleSelection]=\"multiple\"\r\n    [itemSize]=\"item_size\"\r\n    [pageSize]=\"page_size\"\r\n    (scrollChanged)=\"onScroll()\"\r\n    [listItemRef]=\"listOption\"\r\n    (itemDoubleClicked)=\"onDblClickAsync($event)\"\r\n    (itemSelected)=\"onItemSelected($event)\"\r\n    (itemFocused)=\"onEntryFocused($event)\"\r\n    (refreshData)=\"refreshAsync(false)\"\r\n  >\r\n    <ng-template #listOption let-item=\"value\">\r\n      <div *ngIf=\"getIcons(item).length > 0\" class=\"fixed-size-icon-container  lf-no-user-select\">\r\n        <img *ngFor=\"let icon of getIcons(item)\" src=\"{{ icon }}\" alt=\"\" class=\"lf-entry-icon\" />\r\n      </div>\r\n      <div title=\"{{ item?.name }}\" class=\"lf-ellipsis-label lf-no-user-select\">{{ item?.name }}</div>\r\n    </ng-template>\r\n  </lf-selection-list-component>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;justify-content:flex-start;width:100%;max-height:100%;cursor:pointer;flex-grow:1}.lf-repo-entry-container{padding-bottom:10px;overflow:auto;flex:1 1 auto}.lf-repo-entry-container:focus{outline:1px solid #000}#message-display{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:20px 10px 10px;box-sizing:border-box}.lf-repository-browser-header{display:flex;justify-content:space-between;align-items:center;width:100%;height:32px}.lf-repository-browser-header lf-breadcrumbs-component{width:100%;min-width:50px}.lf-no-user-select{-webkit-user-select:none;user-select:none}.fixed-size-icon-container{position:relative;width:24px;min-width:24px;height:24px;margin:5px 10px 5px 5px;display:flex;align-items:center;justify-content:center}.lf-entry-icon{display:block;height:24px;width:24px;overflow:hidden;position:absolute}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.LfBreadcrumbsComponent, selector: "lf-breadcrumbs-component", inputs: ["breadcrumbs"], outputs: ["breadcrumbSelected", "breadcrumbClicked"] }, { kind: "component", type: i2.LfLoaderComponent, selector: "lf-loader-component" }, { kind: "component", type: i5.LfSelectionListComponent, selector: "lf-selection-list-component", inputs: ["itemSize", "pageSize", "listItemRef", "alwaysShowHeader", "listItems", "uniqueIdentifier", "multipleSelection", "columnOrderBy", "columns"], outputs: ["scrollChanged", "itemDoubleClicked", "itemSelected", "itemFocused", "refreshData"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LfRepositoryBrowserComponent, decorators: [{
            type: Component,
            args: [{ selector: 'lf-repository-browser-component', template: "<!--Copyright (c) Laserfiche.\r\nLicensed under the MIT License. See LICENSE in the project root for license information.-->\r\n\r\n<div class=\"lf-repository-browser-header\">\r\n  <lf-breadcrumbs-component [breadcrumbs]=\"breadcrumbs\" (breadcrumbClicked)=\"onBreadcrumbClicked($event)\">\r\n  </lf-breadcrumbs-component>\r\n  <ng-content select=\"lf-toolbar\"></ng-content>\r\n</div>\r\n<div class=\"lf-repo-entry-container\" [attr.tabindex]=\"isLoading || shouldShowErrorMessage || shouldShowEmptyMessage ? 0 : -1\">\r\n  <lf-loader-component *ngIf=\"isLoading\" class=\"lf-text-body lf-no-user-select\"></lf-loader-component>\r\n  <div id=\"message-display\" *ngIf=\"!isLoading && (shouldShowErrorMessage || shouldShowEmptyMessage)\">\r\n    <div *ngIf=\"shouldShowErrorMessage\" class=\"lf-text-body lf-text-error lf-no-user-select\">{{ AN_ERROR_OCCURED | async }}</div>\r\n    <div *ngIf=\"shouldShowEmptyMessage\" class=\"lf-text-body lf-no-user-select\">{{ THIS_FOLDER_IS_EMPTY | async }}</div>\r\n  </div>\r\n\r\n  <lf-selection-list-component\r\n    [hidden]=\"isLoading || shouldShowErrorMessage || shouldShowEmptyMessage\"\r\n    [uniqueIdentifier]=\"repoBrowserUniqueId\"\r\n    [listItems]=\"currentFolderChildren\"\r\n    [multipleSelection]=\"multiple\"\r\n    [itemSize]=\"item_size\"\r\n    [pageSize]=\"page_size\"\r\n    (scrollChanged)=\"onScroll()\"\r\n    [listItemRef]=\"listOption\"\r\n    (itemDoubleClicked)=\"onDblClickAsync($event)\"\r\n    (itemSelected)=\"onItemSelected($event)\"\r\n    (itemFocused)=\"onEntryFocused($event)\"\r\n    (refreshData)=\"refreshAsync(false)\"\r\n  >\r\n    <ng-template #listOption let-item=\"value\">\r\n      <div *ngIf=\"getIcons(item).length > 0\" class=\"fixed-size-icon-container  lf-no-user-select\">\r\n        <img *ngFor=\"let icon of getIcons(item)\" src=\"{{ icon }}\" alt=\"\" class=\"lf-entry-icon\" />\r\n      </div>\r\n      <div title=\"{{ item?.name }}\" class=\"lf-ellipsis-label lf-no-user-select\">{{ item?.name }}</div>\r\n    </ng-template>\r\n  </lf-selection-list-component>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;justify-content:flex-start;width:100%;max-height:100%;cursor:pointer;flex-grow:1}.lf-repo-entry-container{padding-bottom:10px;overflow:auto;flex:1 1 auto}.lf-repo-entry-container:focus{outline:1px solid #000}#message-display{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:20px 10px 10px;box-sizing:border-box}.lf-repository-browser-header{display:flex;justify-content:space-between;align-items:center;width:100%;height:32px}.lf-repository-browser-header lf-breadcrumbs-component{width:100%;min-width:50px}.lf-no-user-select{-webkit-user-select:none;user-select:none}.fixed-size-icon-container{position:relative;width:24px;min-width:24px;height:24px;margin:5px 10px 5px 5px;display:flex;align-items:center;justify-content:center}.lf-entry-icon{display:block;height:24px;width:24px;overflow:hidden;position:absolute}\n"] }]
        }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.MatDialog }, { type: i0.NgZone }, { type: i2.AppLocalizationService }, { type: i0.ElementRef }], propDecorators: { breadcrumbs: [{
                type: Input
            }], currentFolder: [{
                type: Input
            }], item_size: [{
                type: Input
            }], page_size: [{
                type: Input
            }], column_order_by: [{
                type: Input
            }], always_show_header: [{
                type: Input
            }], setColumnsToDisplay: [{
                type: Input
            }], initAsync: [{
                type: Input
            }], isSelectable: [{
                type: Input
            }], multiple: [{
                type: Input
            }], setSelectedNodesAsync: [{
                type: Input
            }], refreshAsync: [{
                type: Input
            }], openSelectedNodesAsync: [{
                type: Input
            }], openFocusedNodeAsync: [{
                type: Input
            }], focus: [{
                type: Input
            }], entryDblClicked: [{
                type: Output
            }], entrySelected: [{
                type: Output
            }], entryFocused: [{
                type: Output
            }], entryList: [{
                type: ViewChild,
                args: [LfSelectionListComponent]
            }] } });

// Copyright (c) Laserfiche.
// Licensed under the MIT License. See LICENSE in the project root for license information.

// Copyright (c) Laserfiche.
// Licensed under the MIT License. See LICENSE in the project root for license information.
class LfRepositoryBrowserModule {
    /** @internal */
    constructor(/** @internal */ injector) {
        const repositoryExplorerElementName = 'lf-repository-browser';
        if (window.customElements && !customElements.get(repositoryExplorerElementName)) {
            const repoExplorerElement = createCustomElement(LfRepositoryBrowserComponent, { injector });
            customElements.define(repositoryExplorerElementName, repoExplorerElement);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LfRepositoryBrowserModule, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: LfRepositoryBrowserModule, bootstrap: [LfRepositoryBrowserComponent], declarations: [LfRepositoryBrowserComponent], imports: [CommonModule,
            FormsModule,
            LfBreadcrumbsModule,
            LfLoaderModule,
            LfSelectionListModule], exports: [LfRepositoryBrowserComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LfRepositoryBrowserModule, imports: [CommonModule,
            FormsModule,
            LfBreadcrumbsModule,
            LfLoaderModule,
            LfSelectionListModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LfRepositoryBrowserModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [LfRepositoryBrowserComponent],
                    imports: [
                        CommonModule,
                        FormsModule,
                        LfBreadcrumbsModule,
                        LfLoaderModule,
                        LfSelectionListModule,
                    ],
                    bootstrap: [LfRepositoryBrowserComponent],
                    exports: [LfRepositoryBrowserComponent],
                    schemas: [CUSTOM_ELEMENTS_SCHEMA],
                }]
        }], ctorParameters: () => [{ type: i0.Injector }] });

// Copyright (c) Laserfiche.
// Licensed under the MIT License. See LICENSE in the project root for license information.

/**
 * Generated bundle index. Do not edit.
 */

export { LfRepositoryBrowserComponent, LfRepositoryBrowserModule };
//# sourceMappingURL=laserfiche-lf-ui-components-lf-repository-browser.mjs.map
