import * as i0 from '@angular/core';
import { Output, Input, Directive, EventEmitter, Optional, Component, NgModule } from '@angular/core';
import { IconDirective, EmptyStateComponent, C8yTranslatePipe, CoreModule } from '@c8y/ngx-components';
import { UpgradeComponent } from '@angular/upgrade/static';
import { gettext } from '@c8y/ngx-components/gettext';
import { mergeWith, uniqBy, reduce, map as map$1, get, filter, identity, property, flatten } from 'lodash-es';
import { BehaviorSubject, combineLatest } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import * as i1 from '@c8y/ngx-components/upgrade/upgraded-services';
import { NgFor, NgStyle, NgIf, AsyncPipe, SlicePipe } from '@angular/common';

class InventoryRoleSelector extends UpgradeComponent {
    constructor(elementRef, injector) {
        super('c8yInventoryRoleSelector', elementRef, injector);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: InventoryRoleSelector, deps: [{ token: i0.ElementRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: InventoryRoleSelector, isStandalone: true, selector: "c8y-inventory-role-selector-upgraded", inputs: { assignedRoles: "assignedRoles", inheritedRoles: "inheritedRoles", inventoryRoles: "inventoryRoles", ownerAllowedRoles: "ownerAllowedRoles", disableEditForExternalUsers: "disableEditForExternalUsers" }, outputs: { onApply: "onApply" }, usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: InventoryRoleSelector, decorators: [{
            type: Directive,
            args: [{ selector: 'c8y-inventory-role-selector-upgraded' }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Injector }], propDecorators: { assignedRoles: [{
                type: Input
            }], inheritedRoles: [{
                type: Input
            }], inventoryRoles: [{
                type: Input
            }], ownerAllowedRoles: [{
                type: Input
            }], disableEditForExternalUsers: [{
                type: Input
            }], onApply: [{
                type: Output
            }] } });

class RolesAssetTreeComponent {
    constructor(c8yUserInventoryRoles, c8yRoles) {
        this.c8yUserInventoryRoles = c8yUserInventoryRoles;
        this.c8yRoles = c8yRoles;
        this.disableEditForExternalUsers = false;
        this.onChangeRoles = new EventEmitter();
        this.onChangeItemCount = new EventEmitter();
        this.noSubgroupTitle = gettext('No subgroups');
        this.manySubgroupsTitle = gettext('Subgroups: {{ count }}');
        this.oneSubgroupTitle = gettext('Subgroup: 1');
        this.clickToOpenTitle = gettext('Click to fetch subgroups');
        this.expandAriaLabel = gettext('Expand');
        this.collapseAriaLabel = gettext('Collapse');
        this.searchTermSubject = new BehaviorSubject('');
        this.flatTreeSubject = new BehaviorSubject([]);
        this.flatAssetTree$ = combineLatest([this.searchTermSubject, this.flatTreeSubject]).pipe(map(([searchTerm, flatTree]) => {
            return flatTree
                .filter(group => group.name.toLowerCase().includes(searchTerm.toLowerCase()))
                .filter(this.filterAsset.bind(this));
        }), tap(flatTree => {
            this.onChangeItemCount.emit(flatTree.length);
        }));
    }
    ngOnInit() {
        this.loadInventoryRoles();
    }
    loadAssetTree() {
        const onlyRootsUser = this.user.owner;
        return this.c8yUserInventoryRoles.listRootGroups({ onlyRootsUser }).then(result => {
            this.rootGroups = result;
            this.updateTree();
        });
    }
    updateTree() {
        this.flatAssetTree = this.c8yUserInventoryRoles.flatTree(this.rootGroups);
        this.setInheritedRoles();
        this.flatTreeSubject.next(this.flatAssetTree);
    }
    loadChildren(mo) {
        if (mo.isOpened) {
            // eslint-disable-next-line no-underscore-dangle
            mo._subGroups = [];
            mo.isOpened = false;
            this.updateTree();
        }
        else {
            this.c8yUserInventoryRoles.loadChildren(mo).then(_ => {
                this.updateTree();
            });
            mo.isOpened = true;
        }
    }
    loadInventoryRoles() {
        this.c8yRoles.list({ pageSize: 1000 }).then(roles => {
            this.inventoryRoles = roles;
        });
    }
    ngOnChanges(changes) {
        if (changes.searchFilter) {
            this.searchTermSubject.next(this.searchFilter || '');
        }
        if (changes.user && !this.loadingAssetTree) {
            this.loadingAssetTree = this.loadAssetTree();
        }
        if (changes.assignedRoles || changes.ownerAssignedRoles) {
            this.loadingAssetTree.then(this.setInheritedRoles.bind(this));
        }
        if (changes.expandGroups && this.expandGroups) {
            this.c8yUserInventoryRoles.expandAll(this.rootGroups, this.updateTree.bind(this));
        }
    }
    setInheritedRoles() {
        if (this.assignedRoles) {
            this.inheritedRoles = this.getInventoryInheritedRoles(this.flatAssetTree, this.assignedRoles);
        }
        if (this.ownerAssignedRoles) {
            const ownerInheritedRoles = this.getInventoryInheritedRoles(this.flatAssetTree, this.ownerAssignedRoles);
            this.ownerAllAssignedRoles = mergeWith(ownerInheritedRoles, this.ownerAssignedRoles, (objValue, srcValue) => {
                if (srcValue) {
                    if (objValue) {
                        return uniqBy(objValue.concat(srcValue.roles), 'id');
                    }
                    return srcValue.roles;
                }
                return objValue;
            });
        }
    }
    getInventoryInheritedRoles(flatTree, assignedRoles) {
        return reduce(flatTree, (inheritedRoles, asset) => {
            // eslint-disable-next-line no-underscore-dangle
            let chain = asset._parentGroups;
            chain = map$1(chain, group => get(assignedRoles, group.id));
            chain = filter(chain, identity);
            chain = map$1(chain, property('roles'));
            chain = flatten(chain);
            chain = uniqBy(chain, 'id');
            inheritedRoles[asset.id] = chain;
            return inheritedRoles;
        }, {});
    }
    onApply(ev, managedObjectId) {
        return this.onChangeRoles.emit({
            managedObjectId: managedObjectId,
            roles: ev.roles
        });
    }
    filterAsset(asset) {
        if (this.ownerAllAssignedRoles) {
            return get(this.ownerAllAssignedRoles, [asset.id, 'length']);
        }
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: RolesAssetTreeComponent, deps: [{ token: i1.Ng1UserInventoryRolesService, optional: true }, { token: i1.Ng1RolesService, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: RolesAssetTreeComponent, isStandalone: true, selector: "c8y-roles-asset-tree-upgraded", inputs: { user: "user", searchFilter: "searchFilter", assignedRoles: "assignedRoles", ownerAssignedRoles: "ownerAssignedRoles", expandGroups: "expandGroups", pageSize: "pageSize", paginationOffset: "paginationOffset", disableEditForExternalUsers: "disableEditForExternalUsers" }, outputs: { onChangeRoles: "onChangeRoles", onChangeItemCount: "onChangeItemCount" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"c8y-list__group m-b-0 no-border-last\">\n  <div\n    class=\"c8y-list__item\"\n    *ngFor=\"\n      let asset of flatAssetTree$ | async | slice: paginationOffset:paginationOffset + pageSize\n    \"\n  >\n    <div\n      class=\"c8y-list__item__block\"\n      [title]=\"\n        (asset._subGroups && asset.isOpened\n          ? asset._subGroups.length\n            ? asset._subGroups.length > 1\n              ? manySubgroupsTitle\n              : oneSubgroupTitle\n            : noSubgroupTitle\n          : clickToOpenTitle\n        ) | translate: { count: asset._subGroups?.length }\n      \"\n    >\n      <div [ngStyle]=\"{ 'padding-left': asset._depth * 8 + 'px' }\"></div>\n      <div class=\"c8y-list__item__icon m-t-4 p-l-0\">\n        <button\n          class=\"btn-clean\"\n          [attr.aria-label]=\"(!asset.isOpened ? expandAriaLabel : collapseAriaLabel) | translate\"\n          type=\"button\"\n          (click)=\"loadChildren(asset)\"\n        >\n          <i\n            class=\"c8y-icon-duocolor\"\n            c8yIcon=\"c8y-group\"\n            *ngIf=\"!asset.isOpened\"\n          ></i>\n          <i\n            class=\"c8y-icon-duocolor\"\n            c8yIcon=\"c8y-group-open\"\n            *ngIf=\"asset.isOpened\"\n          ></i>\n        </button>\n      </div>\n      <div class=\"c8y-list__item__body\">\n        <div class=\"d-flex a-i-center\">\n          <div class=\"col-sm-7 p-l-0 col-xs-12\">\n            <button\n              class=\"btn-clean\"\n              type=\"button\"\n              (click)=\"loadChildren(asset)\"\n            >\n              <span\n                class=\"text-truncate\"\n                [ngStyle]=\"{ cursor: 'pointer' }\"\n                title=\"{{ asset.name }}\"\n              >\n                {{ asset.name }}\n              </span>\n            </button>\n          </div>\n          <div class=\"p-t-8 col-xs-12 visible-xs\"></div>\n          <div class=\"col-sm-5 p-l-0 col-xs-12 p-r-0\">\n            <div class=\"d-flex\">\n              <div class=\"flex-grow form-group-sm max-width-100\">\n                <c8y-inventory-role-selector-upgraded\n                  [ownerAllowedRoles]=\"\n                    ownerAllAssignedRoles ? ownerAllAssignedRoles[asset.id] : undefined\n                  \"\n                  [inheritedRoles]=\"inheritedRoles ? inheritedRoles[asset.id] : undefined\"\n                  [assignedRoles]=\"assignedRoles ? assignedRoles[asset.id] : undefined\"\n                  [inventoryRoles]=\"inventoryRoles\"\n                  [disableEditForExternalUsers]=\"disableEditForExternalUsers\"\n                  (onApply)=\"onApply($event, asset.id)\"\n                  (click)=\"$event.stopPropagation()\"\n                ></c8y-inventory-role-selector-upgraded>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n  <c8y-ui-empty-state\n    [icon]=\"'search'\"\n    [title]=\"'No matching group found among the expanded groups.' | translate\"\n    [subtitle]=\"'Try to expand more groups or to refine your search term.' | translate\"\n    *ngIf=\"searchFilter && !(flatAssetTree$ | async).length\"\n    [horizontal]=\"false\"\n  ></c8y-ui-empty-state>\n</div>\n", dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: InventoryRoleSelector, selector: "c8y-inventory-role-selector-upgraded", inputs: ["assignedRoles", "inheritedRoles", "inventoryRoles", "ownerAllowedRoles", "disableEditForExternalUsers"], outputs: ["onApply"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: SlicePipe, name: "slice" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: RolesAssetTreeComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-roles-asset-tree-upgraded', imports: [
                        NgFor,
                        NgStyle,
                        NgIf,
                        IconDirective,
                        InventoryRoleSelector,
                        EmptyStateComponent,
                        C8yTranslatePipe,
                        AsyncPipe,
                        SlicePipe
                    ], template: "<div class=\"c8y-list__group m-b-0 no-border-last\">\n  <div\n    class=\"c8y-list__item\"\n    *ngFor=\"\n      let asset of flatAssetTree$ | async | slice: paginationOffset:paginationOffset + pageSize\n    \"\n  >\n    <div\n      class=\"c8y-list__item__block\"\n      [title]=\"\n        (asset._subGroups && asset.isOpened\n          ? asset._subGroups.length\n            ? asset._subGroups.length > 1\n              ? manySubgroupsTitle\n              : oneSubgroupTitle\n            : noSubgroupTitle\n          : clickToOpenTitle\n        ) | translate: { count: asset._subGroups?.length }\n      \"\n    >\n      <div [ngStyle]=\"{ 'padding-left': asset._depth * 8 + 'px' }\"></div>\n      <div class=\"c8y-list__item__icon m-t-4 p-l-0\">\n        <button\n          class=\"btn-clean\"\n          [attr.aria-label]=\"(!asset.isOpened ? expandAriaLabel : collapseAriaLabel) | translate\"\n          type=\"button\"\n          (click)=\"loadChildren(asset)\"\n        >\n          <i\n            class=\"c8y-icon-duocolor\"\n            c8yIcon=\"c8y-group\"\n            *ngIf=\"!asset.isOpened\"\n          ></i>\n          <i\n            class=\"c8y-icon-duocolor\"\n            c8yIcon=\"c8y-group-open\"\n            *ngIf=\"asset.isOpened\"\n          ></i>\n        </button>\n      </div>\n      <div class=\"c8y-list__item__body\">\n        <div class=\"d-flex a-i-center\">\n          <div class=\"col-sm-7 p-l-0 col-xs-12\">\n            <button\n              class=\"btn-clean\"\n              type=\"button\"\n              (click)=\"loadChildren(asset)\"\n            >\n              <span\n                class=\"text-truncate\"\n                [ngStyle]=\"{ cursor: 'pointer' }\"\n                title=\"{{ asset.name }}\"\n              >\n                {{ asset.name }}\n              </span>\n            </button>\n          </div>\n          <div class=\"p-t-8 col-xs-12 visible-xs\"></div>\n          <div class=\"col-sm-5 p-l-0 col-xs-12 p-r-0\">\n            <div class=\"d-flex\">\n              <div class=\"flex-grow form-group-sm max-width-100\">\n                <c8y-inventory-role-selector-upgraded\n                  [ownerAllowedRoles]=\"\n                    ownerAllAssignedRoles ? ownerAllAssignedRoles[asset.id] : undefined\n                  \"\n                  [inheritedRoles]=\"inheritedRoles ? inheritedRoles[asset.id] : undefined\"\n                  [assignedRoles]=\"assignedRoles ? assignedRoles[asset.id] : undefined\"\n                  [inventoryRoles]=\"inventoryRoles\"\n                  [disableEditForExternalUsers]=\"disableEditForExternalUsers\"\n                  (onApply)=\"onApply($event, asset.id)\"\n                  (click)=\"$event.stopPropagation()\"\n                ></c8y-inventory-role-selector-upgraded>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n  <c8y-ui-empty-state\n    [icon]=\"'search'\"\n    [title]=\"'No matching group found among the expanded groups.' | translate\"\n    [subtitle]=\"'Try to expand more groups or to refine your search term.' | translate\"\n    *ngIf=\"searchFilter && !(flatAssetTree$ | async).length\"\n    [horizontal]=\"false\"\n  ></c8y-ui-empty-state>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1.Ng1UserInventoryRolesService, decorators: [{
                    type: Optional
                }] }, { type: i1.Ng1RolesService, decorators: [{
                    type: Optional
                }] }], propDecorators: { user: [{
                type: Input
            }], searchFilter: [{
                type: Input
            }], assignedRoles: [{
                type: Input
            }], ownerAssignedRoles: [{
                type: Input
            }], expandGroups: [{
                type: Input
            }], pageSize: [{
                type: Input
            }], paginationOffset: [{
                type: Input
            }], disableEditForExternalUsers: [{
                type: Input
            }], onChangeRoles: [{
                type: Output
            }], onChangeItemCount: [{
                type: Output
            }] } });

class UserRolesModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: UserRolesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: UserRolesModule, imports: [CoreModule, InventoryRoleSelector, RolesAssetTreeComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: UserRolesModule, imports: [CoreModule, RolesAssetTreeComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: UserRolesModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [CoreModule, InventoryRoleSelector, RolesAssetTreeComponent]
                }]
        }] });

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

export { InventoryRoleSelector, RolesAssetTreeComponent, UserRolesModule };
//# sourceMappingURL=c8y-ngx-components-user-roles.mjs.map
