@abp/ng.permission-management
Version:
ABP Framework is a complete open-source infrastructure to create modern web applications by following the best practices and conventions of software development. This package is a part of the [ABP Framework](https://abp.io) and contains client-side files.
824 lines • 76.4 kB
JavaScript
import { ConfigStateService, LocalizationPipe, ListService } from '@abp/ng.core';
import { ToasterService, ModalComponent, ButtonComponent, ModalCloseDirective, ConfirmationService, Confirmation } from '@abp/ng.theme.shared';
import { PermissionsService } from '@abp/ng.permission-management/proxy';
import * as i0 from '@angular/core';
import { inject, DOCUMENT, EventEmitter, signal, computed, ViewChildren, Output, Input, Component, Injectable, InjectionToken, output, ChangeDetectionStrategy, DestroyRef, input, model, effect, untracked, NgModule } from '@angular/core';
import { concat, of, Observable, map, switchMap as switchMap$1, finalize as finalize$1 } from 'rxjs';
import { take, switchMap, finalize, tap } from 'rxjs/operators';
import { NgStyle } from '@angular/common';
import * as i1 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { EntityProp, ExtensionsService, mergeWithDefaultProps, ExtensibleTableComponent, EXTENSIONS_IDENTIFIER } from '@abp/ng.components/extensible';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { LookupSearchComponent } from '@abp/ng.components/lookup';
class PermissionManagementComponent {
constructor() {
this.service = inject(PermissionsService);
this.configState = inject(ConfigStateService);
this.toasterService = inject(ToasterService);
this.document = inject(DOCUMENT);
this.hideBadges = false;
this._visible = false;
this.visibleChange = new EventEmitter();
this.data = { groups: [], entityDisplayName: '' };
this.permissions = [];
this.selectThisTab = false;
this.selectAllTab = false;
this.disableSelectAllTab = false;
this.disabledSelectAllInAllTabs = false;
this.modalBusy = false;
this.filter = signal('', ...(ngDevMode ? [{ debugName: "filter" }] : []));
this.selectedGroupPermissions = [];
this.permissionGroupSignal = signal([], ...(ngDevMode ? [{ debugName: "permissionGroupSignal" }] : []));
this.permissionGroups = computed(() => {
const search = this.filter().toLowerCase().trim();
let groups = this.permissionGroupSignal();
if (!search) {
this.setSelectedGroup(groups[0]);
return groups;
}
const includesSearch = text => text.toLowerCase().includes(search);
groups = groups.filter(group => group.permissions.some(permission => includesSearch(permission.displayName) || includesSearch(group.displayName)));
if (groups.length) {
this.setSelectedGroup(groups[0]);
}
else {
this.selectedGroupPermissions = [];
}
return groups;
}, ...(ngDevMode ? [{ debugName: "permissionGroups" }] : []));
this.trackByFn = (_, item) => item.name;
}
get visible() {
return this._visible;
}
set visible(value) {
if (value === this._visible) {
return;
}
if (value) {
this.openModal().subscribe(() => {
this._visible = true;
this.visibleChange.emit(true);
concat(this.selectAllInAllTabsRef.changes, this.selectAllInThisTabsRef.changes)
.pipe(take(1))
.subscribe(() => {
this.initModal();
});
});
}
else {
this.setSelectedGroup(null);
this._visible = false;
this.visibleChange.emit(false);
this.filter.set('');
}
}
getChecked(name) {
return (this.permissions.find(per => per.name === name) || { isGranted: false }).isGranted;
}
setSelectedGroup(group) {
this.selectedGroup = group;
if (!this.selectedGroup) {
this.selectedGroupPermissions = [];
return;
}
const margin = `margin-${this.document.body?.dir === 'rtl' ? 'right' : 'left'}.px`;
const permissions = (this.data.groups.find(group => group.name === this.selectedGroup?.name) || {}).permissions ||
[];
this.selectedGroupPermissions = permissions.map(permission => ({
...permission,
style: { [margin]: findMargin(permissions, permission) },
isGranted: (this.permissions.find(per => per.name === permission.name) || {}).isGranted,
}));
}
setDisabled(permissions) {
if (permissions.length) {
this.disableSelectAllTab = permissions.every(permission => permission.isGranted &&
permission.grantedProviders?.every(p => p.providerName !== this.providerName));
}
else {
this.disableSelectAllTab = false;
}
}
isGrantedByOtherProviderName(grantedProviders) {
if (grantedProviders.length) {
return grantedProviders.findIndex(p => p.providerName !== this.providerName) > -1;
}
return false;
}
onClickCheckbox(clickedPermission) {
const { isGranted, grantedProviders } = clickedPermission;
if (isGranted && this.isGrantedByOtherProviderName(grantedProviders)) {
return;
}
this.setSelectedGroup(this.selectedGroup);
setTimeout(() => {
this.updatePermissionStatus(clickedPermission);
this.updateSelectedGroupPermissions(clickedPermission);
this.setParentClicked(clickedPermission);
this.setTabCheckboxState();
this.setGrantCheckboxState();
}, 0);
}
updatePermissionStatus(clickedPermission) {
this.permissions = this.permissions.map(permission => {
const isExactMatch = clickedPermission.name == permission.name;
const isParentOfPermission = clickedPermission.parentName === permission.name;
const isChildOfPermission = clickedPermission.name === permission.parentName;
if (isExactMatch) {
return { ...permission, isGranted: !permission.isGranted };
}
if (isChildOfPermission && permission.isGranted) {
return { ...permission, isGranted: false };
}
if (isParentOfPermission && !permission.isGranted) {
return { ...permission, isGranted: true };
}
return permission;
});
}
setParentClicked(clickedPermission) {
if (clickedPermission.parentName) {
const parentPermissions = findParentPermissions(this.permissions, clickedPermission);
if (parentPermissions.length > 0) {
const parentNames = new Set(parentPermissions.map(parent => parent.name));
this.permissions = this.permissions.map(per => {
let updatedIsGranted = per.isGranted;
if (per.parentName === clickedPermission.name && !clickedPermission.isGranted) {
updatedIsGranted = false;
}
if (parentNames.has(per.name)) {
updatedIsGranted = true;
}
return { ...per, isGranted: updatedIsGranted };
});
}
return;
}
this.permissions = this.permissions.map(per => {
const parents = findParentPermissions(this.permissions, per);
if (parents.length > 0) {
const rootParent = parents[parents.length - 1];
if (rootParent.name === clickedPermission.name && !rootParent.isGranted) {
return { ...per, isGranted: false };
}
}
return per;
});
}
updateSelectedGroupPermissions(clickedPermissions) {
this.selectedGroupPermissions = this.selectedGroupPermissions.map(per => {
if (per.name === clickedPermissions.name) {
per.isGranted = !per.isGranted;
}
return per;
});
}
setTabCheckboxState() {
const selectablePermissions = this.selectedGroupPermissions.filter(per => per.grantedProviders.every(p => p.providerName === this.providerName));
const selectedPermissions = selectablePermissions.filter(per => per.isGranted);
const element = this.document.querySelector('#select-all-in-this-tabs');
if (!element) {
return;
}
if (selectedPermissions.length === selectablePermissions.length) {
element.indeterminate = false;
this.selectThisTab = true;
}
else if (selectedPermissions.length === 0) {
element.indeterminate = false;
this.selectThisTab = false;
}
else {
element.indeterminate = true;
}
}
setGrantCheckboxState() {
const selectablePermissions = this.permissions.filter(per => per.grantedProviders.every(p => p.providerName === this.providerName));
const selectedAllPermissions = selectablePermissions.filter(per => per.isGranted);
const checkboxElement = this.document.querySelector('#select-all-in-all-tabs');
if (selectedAllPermissions.length === selectablePermissions.length) {
checkboxElement.indeterminate = false;
this.selectAllTab = true;
}
else if (selectedAllPermissions.length === 0) {
checkboxElement.indeterminate = false;
this.selectAllTab = false;
}
else {
checkboxElement.indeterminate = true;
}
}
onClickSelectThisTab() {
this.selectedGroupPermissions.forEach(permission => {
if (permission.isGranted && this.isGrantedByOtherProviderName(permission.grantedProviders))
return;
const index = this.permissions.findIndex(per => per.name === permission.name);
this.permissions = [
...this.permissions.slice(0, index),
{ ...this.permissions[index], isGranted: !this.selectThisTab },
...this.permissions.slice(index + 1),
];
});
this.setGrantCheckboxState();
}
onClickSelectAll() {
if (this.filter()) {
this.filter.set('');
}
this.permissions = this.permissions.map(permission => ({
...permission,
isGranted: this.isGrantedByOtherProviderName(permission.grantedProviders) || !this.selectAllTab,
}));
if (!this.disableSelectAllTab) {
this.selectThisTab = !this.selectAllTab;
this.setTabCheckboxState();
if (this.filter()) {
this.setGrantCheckboxState();
}
}
this.onChangeGroup(this.selectedGroup);
}
onChangeGroup(group) {
this.setDisabled(group.permissions);
this.setSelectedGroup(group);
this.setTabCheckboxState();
}
submit() {
const unchangedPermissions = getPermissions(this.data.groups);
const changedPermissions = this.permissions
.filter(per => (unchangedPermissions.find(unchanged => unchanged.name === per.name) || {}).isGranted ===
per.isGranted
? false
: true)
.map(({ name, isGranted }) => ({ name, isGranted }));
if (!changedPermissions.length) {
this.visible = false;
return;
}
this.modalBusy = true;
this.service
.update(this.providerName, this.providerKey, { permissions: changedPermissions })
.pipe(switchMap(() => this.shouldFetchAppConfig() ? this.configState.refreshAppState() : of(null)), finalize(() => (this.modalBusy = false)))
.subscribe(() => {
this.visible = false;
this.toasterService.success('AbpUi::SavedSuccessfully');
});
}
openModal() {
if (!this.providerKey || !this.providerName) {
throw new Error('Provider Key and Provider Name are required.');
}
return this.service.get(this.providerName, this.providerKey).pipe(tap((permissionRes) => {
const { groups } = permissionRes || {};
this.data = permissionRes;
this.permissionGroupSignal.set(groups);
this.permissions = getPermissions(groups);
this.setSelectedGroup(groups[0]);
this.disabledSelectAllInAllTabs = this.permissions.every(per => per.isGranted &&
per.grantedProviders.every(provider => provider.providerName !== this.providerName));
}));
}
initModal() {
// TODO: Refactor
setTimeout(() => {
this.setDisabled(this.selectedGroup?.permissions || []);
this.setTabCheckboxState();
this.setGrantCheckboxState();
});
}
getAssignedCount(groupName) {
return this.permissions.reduce((acc, val) => (val.groupName === groupName && val.isGranted ? acc + 1 : acc), 0);
}
shouldFetchAppConfig() {
const currentUser = this.configState.getOne('currentUser');
if (this.providerName === 'R')
return currentUser.roles.some(role => role === this.providerKey);
if (this.providerName === 'U')
return currentUser.id === this.providerKey;
return false;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: PermissionManagementComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: PermissionManagementComponent, isStandalone: true, selector: "abp-permission-management", inputs: { providerName: "providerName", providerKey: "providerKey", hideBadges: "hideBadges", entityDisplayName: "entityDisplayName", visible: "visible" }, outputs: { visibleChange: "visibleChange" }, viewQueries: [{ propertyName: "selectAllInThisTabsRef", predicate: ["selectAllInThisTabsRef"], descendants: true }, { propertyName: "selectAllInAllTabsRef", predicate: ["selectAllInAllTabsRef"], descendants: true }], exportAs: ["abpPermissionManagement"], ngImport: i0, template: "<abp-modal [(visible)]=\"visible\" [busy]=\"modalBusy\" [options]=\"{ size: 'lg', scrollable: false }\">\r\n @if (data.entityDisplayName || entityDisplayName) {\r\n <ng-template #abpHeader>\r\n <h4>\r\n {{ 'AbpPermissionManagement::Permissions' | abpLocalization }} -\r\n {{ entityDisplayName || data.entityDisplayName }}\r\n </h4>\r\n </ng-template>\r\n <ng-template #abpBody>\r\n <div class=\"row d-flex align-items-center mb-2\">\r\n <div class=\"col\">\r\n <div class=\"input-group mb-2\">\r\n <span class=\"input-group-text\" id=\"basic-addon1\"><i class=\"bi bi-search\"></i></span>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n id=\"permission-search\"\r\n placeholder=\"Filter\"\r\n [ngModel]=\"filter()\"\r\n (ngModelChange)=\"filter.set($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"col-auto\">\r\n <div class=\"form-check mb-2\">\r\n <input\r\n #selectAllInAllTabsRef\r\n type=\"checkbox\"\r\n id=\"select-all-in-all-tabs\"\r\n name=\"select-all-in-all-tabs\"\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"selectAllTab\"\r\n (click)=\"onClickSelectAll()\"\r\n [disabled]=\"disabledSelectAllInAllTabs\"\r\n />\r\n <label class=\"form-check-label\" for=\"select-all-in-all-tabs\">{{\r\n 'AbpPermissionManagement::SelectAllInAllTabs' | abpLocalization\r\n }}</label>\r\n </div>\r\n </div>\r\n </div>\r\n <fieldset class=\"border rounded-4 p-3\">\r\n <legend class=\"px-1 h5 mb-0\">\r\n {{ 'AbpPermissionManagement::PermissionGroup' | abpLocalization }}\r\n </legend>\r\n <div class=\"row\">\r\n <div class=\"col-md-4\">\r\n <div class=\"overflow-auto lpx-scroll-pills-container scroll-in-modal\">\r\n <ul class=\"nav nav-pills flex-column\">\r\n @for (group of permissionGroups(); track $index) {\r\n <li class=\"border nav-item\">\r\n @if ({ assignedCount: getAssignedCount(group.name) }; as count) {\r\n <a\r\n class=\"nav-link pointer\"\r\n [class.active]=\"selectedGroup?.name === group?.name\"\r\n (click)=\"onChangeGroup(group)\"\r\n (select)=\"setDisabled(group.permissions)\"\r\n >\r\n <div [class.font-weight-bold]=\"count.assignedCount\">\r\n {{ group?.displayName }}\r\n @if (count.assignedCount > 0) {\r\n <span>({{ count.assignedCount }})</span>\r\n }\r\n </div>\r\n </a>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-8 scroll-in-modal\">\r\n <div class=\"ps-1\">\r\n @if (selectedGroupPermissions.length) {\r\n <div class=\"form-check mb-2\">\r\n <input\r\n #selectAllInThisTabsRef\r\n type=\"checkbox\"\r\n id=\"select-all-in-this-tabs\"\r\n name=\"select-all-in-this-tabs\"\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"selectThisTab\"\r\n [disabled]=\"disableSelectAllTab\"\r\n (click)=\"onClickSelectThisTab()\"\r\n />\r\n <label class=\"form-check-label\" for=\"select-all-in-this-tabs\">{{\r\n 'AbpPermissionManagement::SelectAllInThisTab' | abpLocalization\r\n }}</label>\r\n </div>\r\n <hr class=\"my-2\" />\r\n @for (permission of selectedGroupPermissions; track $index; let i = $index) {\r\n <div [ngStyle]=\"permission.style\" class=\"form-check mb-2\">\r\n <input\r\n #permissionCheckbox\r\n type=\"checkbox\"\r\n [checked]=\"getChecked(permission.name)\"\r\n [value]=\"getChecked(permission.name)\"\r\n [attr.id]=\"permission.name\"\r\n class=\"form-check-input\"\r\n [disabled]=\"isGrantedByOtherProviderName(permission.grantedProviders)\"\r\n (click)=\"onClickCheckbox(permission, permissionCheckbox.value)\"\r\n />\r\n <label class=\"form-check-label\" [attr.for]=\"permission.name\"\r\n >{{ permission.displayName }}\r\n @if (!hideBadges) {\r\n @for (provider of permission.grantedProviders; track $index) {\r\n <span class=\"badge bg-primary text-dark\"\r\n >{{ provider.providerName }}: {{ provider.providerKey }}</span\r\n >\r\n }\r\n }\r\n </label>\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </fieldset>\r\n </ng-template>\r\n <ng-template #abpFooter>\r\n <button type=\"button\" class=\"btn btn-outline-primary\" abpClose>\r\n {{ 'AbpIdentity::Cancel' | abpLocalization }}\r\n </button>\r\n <abp-button iconClass=\"fa fa-check\" (click)=\"submit()\">{{\r\n 'AbpIdentity::Save' | abpLocalization\r\n }}</abp-button>\r\n </ng-template>\r\n }\r\n</abp-modal>\r\n", styles: [".scroll-in-modal{overflow:auto;max-height:calc(100vh - 23.1rem)}.lpx-scroll-pills-container ul{display:block;overflow-y:auto}@media(max-width:768px){.scroll-in-modal{max-height:calc(100vh - 15rem)}.lpx-scroll-pills-container ul{max-height:500px}}fieldset legend{float:none;width:auto}.lpx-scroll-pills-container .tab-content{padding-top:0!important;padding-bottom:0!important}.lpx-scroll-pills-container ul li{margin-bottom:10px;border-radius:10px}.lpx-scroll-pills-container ul li a.active{color:#fff!important;border-color:#6c5dd3!important;background-color:#6c5dd3!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ModalComponent, selector: "abp-modal", inputs: ["visible", "busy", "options", "suppressUnsavedChangesWarning"], outputs: ["visibleChange", "init", "appear", "disappear"] }, { kind: "component", type: ButtonComponent, selector: "abp-button", inputs: ["buttonId", "buttonClass", "buttonType", "formName", "iconClass", "loading", "disabled", "attributes"], outputs: ["click", "focus", "blur", "abpClick", "abpFocus", "abpBlur"] }, { kind: "directive", type: ModalCloseDirective, selector: "[abpClose]" }, { kind: "pipe", type: LocalizationPipe, name: "abpLocalization" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: PermissionManagementComponent, decorators: [{
type: Component,
args: [{ selector: 'abp-permission-management', exportAs: 'abpPermissionManagement', imports: [
FormsModule,
NgStyle,
ModalComponent,
LocalizationPipe,
ButtonComponent,
ModalCloseDirective,
], template: "<abp-modal [(visible)]=\"visible\" [busy]=\"modalBusy\" [options]=\"{ size: 'lg', scrollable: false }\">\r\n @if (data.entityDisplayName || entityDisplayName) {\r\n <ng-template #abpHeader>\r\n <h4>\r\n {{ 'AbpPermissionManagement::Permissions' | abpLocalization }} -\r\n {{ entityDisplayName || data.entityDisplayName }}\r\n </h4>\r\n </ng-template>\r\n <ng-template #abpBody>\r\n <div class=\"row d-flex align-items-center mb-2\">\r\n <div class=\"col\">\r\n <div class=\"input-group mb-2\">\r\n <span class=\"input-group-text\" id=\"basic-addon1\"><i class=\"bi bi-search\"></i></span>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n id=\"permission-search\"\r\n placeholder=\"Filter\"\r\n [ngModel]=\"filter()\"\r\n (ngModelChange)=\"filter.set($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"col-auto\">\r\n <div class=\"form-check mb-2\">\r\n <input\r\n #selectAllInAllTabsRef\r\n type=\"checkbox\"\r\n id=\"select-all-in-all-tabs\"\r\n name=\"select-all-in-all-tabs\"\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"selectAllTab\"\r\n (click)=\"onClickSelectAll()\"\r\n [disabled]=\"disabledSelectAllInAllTabs\"\r\n />\r\n <label class=\"form-check-label\" for=\"select-all-in-all-tabs\">{{\r\n 'AbpPermissionManagement::SelectAllInAllTabs' | abpLocalization\r\n }}</label>\r\n </div>\r\n </div>\r\n </div>\r\n <fieldset class=\"border rounded-4 p-3\">\r\n <legend class=\"px-1 h5 mb-0\">\r\n {{ 'AbpPermissionManagement::PermissionGroup' | abpLocalization }}\r\n </legend>\r\n <div class=\"row\">\r\n <div class=\"col-md-4\">\r\n <div class=\"overflow-auto lpx-scroll-pills-container scroll-in-modal\">\r\n <ul class=\"nav nav-pills flex-column\">\r\n @for (group of permissionGroups(); track $index) {\r\n <li class=\"border nav-item\">\r\n @if ({ assignedCount: getAssignedCount(group.name) }; as count) {\r\n <a\r\n class=\"nav-link pointer\"\r\n [class.active]=\"selectedGroup?.name === group?.name\"\r\n (click)=\"onChangeGroup(group)\"\r\n (select)=\"setDisabled(group.permissions)\"\r\n >\r\n <div [class.font-weight-bold]=\"count.assignedCount\">\r\n {{ group?.displayName }}\r\n @if (count.assignedCount > 0) {\r\n <span>({{ count.assignedCount }})</span>\r\n }\r\n </div>\r\n </a>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-8 scroll-in-modal\">\r\n <div class=\"ps-1\">\r\n @if (selectedGroupPermissions.length) {\r\n <div class=\"form-check mb-2\">\r\n <input\r\n #selectAllInThisTabsRef\r\n type=\"checkbox\"\r\n id=\"select-all-in-this-tabs\"\r\n name=\"select-all-in-this-tabs\"\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"selectThisTab\"\r\n [disabled]=\"disableSelectAllTab\"\r\n (click)=\"onClickSelectThisTab()\"\r\n />\r\n <label class=\"form-check-label\" for=\"select-all-in-this-tabs\">{{\r\n 'AbpPermissionManagement::SelectAllInThisTab' | abpLocalization\r\n }}</label>\r\n </div>\r\n <hr class=\"my-2\" />\r\n @for (permission of selectedGroupPermissions; track $index; let i = $index) {\r\n <div [ngStyle]=\"permission.style\" class=\"form-check mb-2\">\r\n <input\r\n #permissionCheckbox\r\n type=\"checkbox\"\r\n [checked]=\"getChecked(permission.name)\"\r\n [value]=\"getChecked(permission.name)\"\r\n [attr.id]=\"permission.name\"\r\n class=\"form-check-input\"\r\n [disabled]=\"isGrantedByOtherProviderName(permission.grantedProviders)\"\r\n (click)=\"onClickCheckbox(permission, permissionCheckbox.value)\"\r\n />\r\n <label class=\"form-check-label\" [attr.for]=\"permission.name\"\r\n >{{ permission.displayName }}\r\n @if (!hideBadges) {\r\n @for (provider of permission.grantedProviders; track $index) {\r\n <span class=\"badge bg-primary text-dark\"\r\n >{{ provider.providerName }}: {{ provider.providerKey }}</span\r\n >\r\n }\r\n }\r\n </label>\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </fieldset>\r\n </ng-template>\r\n <ng-template #abpFooter>\r\n <button type=\"button\" class=\"btn btn-outline-primary\" abpClose>\r\n {{ 'AbpIdentity::Cancel' | abpLocalization }}\r\n </button>\r\n <abp-button iconClass=\"fa fa-check\" (click)=\"submit()\">{{\r\n 'AbpIdentity::Save' | abpLocalization\r\n }}</abp-button>\r\n </ng-template>\r\n }\r\n</abp-modal>\r\n", styles: [".scroll-in-modal{overflow:auto;max-height:calc(100vh - 23.1rem)}.lpx-scroll-pills-container ul{display:block;overflow-y:auto}@media(max-width:768px){.scroll-in-modal{max-height:calc(100vh - 15rem)}.lpx-scroll-pills-container ul{max-height:500px}}fieldset legend{float:none;width:auto}.lpx-scroll-pills-container .tab-content{padding-top:0!important;padding-bottom:0!important}.lpx-scroll-pills-container ul li{margin-bottom:10px;border-radius:10px}.lpx-scroll-pills-container ul li a.active{color:#fff!important;border-color:#6c5dd3!important;background-color:#6c5dd3!important}\n"] }]
}], propDecorators: { providerName: [{
type: Input
}], providerKey: [{
type: Input
}], hideBadges: [{
type: Input
}], entityDisplayName: [{
type: Input
}], visible: [{
type: Input
}], visibleChange: [{
type: Output
}], selectAllInThisTabsRef: [{
type: ViewChildren,
args: ['selectAllInThisTabsRef']
}], selectAllInAllTabsRef: [{
type: ViewChildren,
args: ['selectAllInAllTabsRef']
}] } });
function findParentPermissions(permissions, permission) {
const permissionMap = new Map(permissions.map(p => [p.name, p]));
let currentPermission = permissionMap.get(permission.name) ?? null;
const parentPermissions = [];
while (currentPermission && currentPermission.parentName) {
const parentPermission = permissionMap.get(currentPermission.parentName);
if (!parentPermission) {
break;
}
parentPermissions.push(parentPermission);
currentPermission = parentPermission;
}
return parentPermissions;
}
function findMargin(permissions, permission) {
const parentPermission = permissions.find(per => per.name === permission.parentName);
if (parentPermission && parentPermission.parentName) {
let margin = 20;
return (margin += findMargin(permissions, parentPermission));
}
return parentPermission ? 20 : 0;
}
function getPermissions(groups) {
return groups.reduce((acc, val) => [
...acc,
...val.permissions.map(p => ({ ...p, groupName: val.name || '' })),
], []);
}
var eResourcePermissionViewModes;
(function (eResourcePermissionViewModes) {
eResourcePermissionViewModes["List"] = "list";
eResourcePermissionViewModes["Add"] = "add";
eResourcePermissionViewModes["Edit"] = "edit";
})(eResourcePermissionViewModes || (eResourcePermissionViewModes = {}));
class ResourcePermissionStateService {
constructor() {
// View state
this.viewMode = signal(eResourcePermissionViewModes.List, ...(ngDevMode ? [{ debugName: "viewMode" }] : []));
this.modalBusy = signal(false, ...(ngDevMode ? [{ debugName: "modalBusy" }] : []));
this.hasResourcePermission = signal(false, ...(ngDevMode ? [{ debugName: "hasResourcePermission" }] : []));
this.hasProviderKeyLookupService = signal(false, ...(ngDevMode ? [{ debugName: "hasProviderKeyLookupService" }] : []));
// Resource data
this.resourceName = signal('', ...(ngDevMode ? [{ debugName: "resourceName" }] : []));
this.resourceKey = signal('', ...(ngDevMode ? [{ debugName: "resourceKey" }] : []));
this.resourceDisplayName = signal(undefined, ...(ngDevMode ? [{ debugName: "resourceDisplayName" }] : []));
// Permissions data
this.allResourcePermissions = signal([], ...(ngDevMode ? [{ debugName: "allResourcePermissions" }] : []));
this.resourcePermissions = signal([], ...(ngDevMode ? [{ debugName: "resourcePermissions" }] : []));
this.totalCount = signal(0, ...(ngDevMode ? [{ debugName: "totalCount" }] : []));
this.permissionDefinitions = signal([], ...(ngDevMode ? [{ debugName: "permissionDefinitions" }] : []));
this.permissionsWithProvider = signal([], ...(ngDevMode ? [{ debugName: "permissionsWithProvider" }] : []));
this.selectedPermissions = signal([], ...(ngDevMode ? [{ debugName: "selectedPermissions" }] : []));
// Provider data
this.providers = signal([], ...(ngDevMode ? [{ debugName: "providers" }] : []));
this.selectedProviderName = signal('', ...(ngDevMode ? [{ debugName: "selectedProviderName" }] : []));
this.selectedProviderKey = signal('', ...(ngDevMode ? [{ debugName: "selectedProviderKey" }] : []));
// Edit mode specific
this.editProviderName = signal('', ...(ngDevMode ? [{ debugName: "editProviderName" }] : []));
this.editProviderKey = signal('', ...(ngDevMode ? [{ debugName: "editProviderKey" }] : []));
// Search state
this.searchFilter = signal('', ...(ngDevMode ? [{ debugName: "searchFilter" }] : []));
this.searchResults = signal([], ...(ngDevMode ? [{ debugName: "searchResults" }] : []));
this.showDropdown = signal(false, ...(ngDevMode ? [{ debugName: "showDropdown" }] : []));
// Computed properties
this.isAddMode = computed(() => this.viewMode() === eResourcePermissionViewModes.Add, ...(ngDevMode ? [{ debugName: "isAddMode" }] : []));
this.isEditMode = computed(() => this.viewMode() === eResourcePermissionViewModes.Edit, ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
this.isListMode = computed(() => this.viewMode() === eResourcePermissionViewModes.List, ...(ngDevMode ? [{ debugName: "isListMode" }] : []));
this.currentPermissionsList = computed(() => this.isAddMode() ? this.permissionDefinitions() : this.permissionsWithProvider(), ...(ngDevMode ? [{ debugName: "currentPermissionsList" }] : []));
this.allPermissionsSelected = computed(() => {
const definitions = this.currentPermissionsList();
return definitions.length > 0 &&
definitions.every(p => this.selectedPermissions().includes(p.name || ''));
}, ...(ngDevMode ? [{ debugName: "allPermissionsSelected" }] : []));
this.canSave = computed(() => {
if (this.isAddMode()) {
return !!this.selectedProviderKey() && this.selectedPermissions().length > 0;
}
return this.selectedPermissions().length >= 0;
}, ...(ngDevMode ? [{ debugName: "canSave" }] : []));
}
// State transition methods
goToListMode() {
this.viewMode.set(eResourcePermissionViewModes.List);
this.selectedPermissions.set([]);
}
goToAddMode() {
this.viewMode.set(eResourcePermissionViewModes.Add);
this.selectedPermissions.set([]);
this.selectedProviderKey.set('');
this.searchResults.set([]);
this.searchFilter.set('');
}
prepareEditMode(grant) {
this.editProviderName.set(grant.providerName || '');
this.editProviderKey.set(grant.providerKey || '');
}
setEditModePermissions(permissions) {
this.permissionsWithProvider.set(permissions);
this.selectedPermissions.set(permissions.filter(p => p.isGranted).map(p => p.name || ''));
this.viewMode.set(eResourcePermissionViewModes.Edit);
}
// Permission selection methods
togglePermission(permissionName) {
const current = this.selectedPermissions();
if (current.includes(permissionName)) {
this.selectedPermissions.set(current.filter(p => p !== permissionName));
}
else {
this.selectedPermissions.set([...current, permissionName]);
}
}
toggleAllPermissions(selectAll) {
const permissions = this.currentPermissionsList();
this.selectedPermissions.set(selectAll ? permissions.map(p => p.name || '') : []);
}
isPermissionSelected(permissionName) {
return this.selectedPermissions().includes(permissionName);
}
// Provider search methods
onProviderChange(providerName) {
this.selectedProviderName.set(providerName);
this.selectedProviderKey.set('');
this.searchResults.set([]);
this.searchFilter.set('');
}
selectProviderKey(key) {
this.selectedProviderKey.set(key.providerKey || '');
this.searchFilter.set(key.providerDisplayName || key.providerKey || '');
this.searchResults.set([]);
this.showDropdown.set(false);
}
// Reset all state
reset() {
this.viewMode.set(eResourcePermissionViewModes.List);
this.allResourcePermissions.set([]);
this.resourcePermissions.set([]);
this.totalCount.set(0);
this.selectedProviderName.set('');
this.selectedProviderKey.set('');
this.searchFilter.set('');
this.selectedPermissions.set([]);
this.searchResults.set([]);
this.editProviderName.set('');
this.editProviderKey.set('');
}
// Data loading helpers
setResourceData(permissions) {
this.allResourcePermissions.set(permissions);
this.totalCount.set(permissions.length);
}
setProviders(providers) {
this.providers.set(providers);
this.hasProviderKeyLookupService.set(providers.length > 0);
if (providers.length) {
this.selectedProviderName.set(providers[0].name || '');
}
}
setDefinitions(permissions) {
this.permissionDefinitions.set(permissions);
this.hasResourcePermission.set(permissions.length > 0);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ResourcePermissionStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ResourcePermissionStateService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ResourcePermissionStateService, decorators: [{
type: Injectable
}] });
const DEFAULT_RESOURCE_PERMISSION_ENTITY_PROPS = EntityProp.createMany([
{
type: "string" /* ePropType.String */,
name: 'providerWithKey',
displayName: 'AbpPermissionManagement::Provider',
sortable: false,
valueResolver: data => {
const providerName = data.record.providerName || '';
const providerDisplayName = data.record.providerDisplayName || data.record.providerKey || '';
// Get first letter of provider name for abbreviation
const abbr = providerName.charAt(0).toUpperCase();
return of(`<span class="d-inline-block bg-light rounded-pill px-2 me-1 ms-1 mb-1" title="${data.record.providerNameDisplayName || providerName}">${abbr}</span>${providerDisplayName}`);
},
},
{
type: "string" /* ePropType.String */,
name: 'permissions',
displayName: 'AbpPermissionManagement::Permissions',
sortable: false,
valueResolver: data => {
const permissions = data.record.permissions || [];
const pills = permissions
.map(p => `<span class="d-inline-block bg-light rounded-pill px-2 me-1 mb-1">${p.displayName}</span>`)
.join('');
return of(pills);
},
},
]);
const DEFAULT_RESOURCE_PERMISSION_ENTITY_PROPS_MAP = {
["PermissionManagement.ResourcePermissionsComponent" /* ePermissionManagementComponents.ResourcePermissions */]: DEFAULT_RESOURCE_PERMISSION_ENTITY_PROPS,
};
const RESOURCE_PERMISSION_ENTITY_PROP_CONTRIBUTORS = new InjectionToken('RESOURCE_PERMISSION_ENTITY_PROP_CONTRIBUTORS');
function configureResourcePermissionExtensions() {
const extensions = inject(ExtensionsService);
const config = { optional: true };
const propContributors = inject(RESOURCE_PERMISSION_ENTITY_PROP_CONTRIBUTORS, config) || {};
mergeWithDefaultProps(extensions.entityProps, DEFAULT_RESOURCE_PERMISSION_ENTITY_PROPS_MAP, propContributors);
}
class ResourcePermissionListComponent {
constructor() {
this.state = inject(ResourcePermissionStateService);
this.list = inject(ListService);
this.addClicked = output();
this.editClicked = output();
this.deleteClicked = output();
configureResourcePermissionExtensions();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ResourcePermissionListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ResourcePermissionListComponent, isStandalone: true, selector: "abp-resource-permission-list", outputs: { addClicked: "addClicked", editClicked: "editClicked", deleteClicked: "deleteClicked" }, providers: [
ListService,
{
provide: EXTENSIONS_IDENTIFIER,
useValue: "PermissionManagement.ResourcePermissionsComponent" /* ePermissionManagementComponents.ResourcePermissions */,
},
], ngImport: i0, template: "<div class=\"d-grid gap-2 mb-3 d-md-flex justify-content-md-end\">\r\n <button class=\"btn btn-sm btn-primary\" type=\"button\" (click)=\"addClicked.emit()\">\r\n <i class=\"fa fa-plus me-1\"></i>\r\n {{ 'AbpPermissionManagement::AddResourcePermission' | abpLocalization }}\r\n </button>\r\n</div>\r\n\r\n<ng-template #actionsTemplate let-row>\r\n <div class=\"btn-group btn-group-sm\" role=\"group\">\r\n <button\r\n class=\"btn btn-outline-primary\"\r\n type=\"button\"\r\n (click)=\"editClicked.emit(row)\"\r\n [title]=\"'AbpUi::Edit' | abpLocalization\"\r\n >\r\n <i class=\"fa fa-edit\"></i>\r\n </button>\r\n <button\r\n class=\"btn btn-outline-danger\"\r\n type=\"button\"\r\n (click)=\"deleteClicked.emit(row)\"\r\n [title]=\"'AbpUi::Delete' | abpLocalization\"\r\n >\r\n <i class=\"fa fa-trash\"></i>\r\n </button>\r\n </div>\r\n</ng-template>\r\n\r\n@if (state.resourcePermissions().length > 0) {\r\n <abp-extensible-table\r\n [data]=\"state.resourcePermissions()\"\r\n [recordsTotal]=\"state.totalCount()\"\r\n [list]=\"list\"\r\n [actionsTemplate]=\"actionsTemplate\"\r\n actionsText=\"AbpUi::Actions\"\r\n />\r\n} @else {\r\n <div class=\"alert alert-info\">\r\n {{ 'AbpPermissionManagement::NoPermissionsAssigned' | abpLocalization }}\r\n </div>\r\n}\r\n", dependencies: [{ kind: "component", type: ExtensibleTableComponent, selector: "abp-extensible-table", inputs: ["actionsText", "data", "list", "recordsTotal", "actionsColumnWidth", "actionsTemplate", "selectable", "selectionType", "selected", "infiniteScroll", "isLoading", "scrollThreshold", "tableHeight"], outputs: ["tableActivate", "selectionChange", "loadMore"], exportAs: ["abpExtensibleTable"] }, { kind: "pipe", type: LocalizationPipe, name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ResourcePermissionListComponent, decorators: [{
type: Component,
args: [{ selector: 'abp-resource-permission-list', providers: [
ListService,
{
provide: EXTENSIONS_IDENTIFIER,
useValue: "PermissionManagement.ResourcePermissionsComponent" /* ePermissionManagementComponents.ResourcePermissions */,
},
], imports: [LocalizationPipe, ExtensibleTableComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"d-grid gap-2 mb-3 d-md-flex justify-content-md-end\">\r\n <button class=\"btn btn-sm btn-primary\" type=\"button\" (click)=\"addClicked.emit()\">\r\n <i class=\"fa fa-plus me-1\"></i>\r\n {{ 'AbpPermissionManagement::AddResourcePermission' | abpLocalization }}\r\n </button>\r\n</div>\r\n\r\n<ng-template #actionsTemplate let-row>\r\n <div class=\"btn-group btn-group-sm\" role=\"group\">\r\n <button\r\n class=\"btn btn-outline-primary\"\r\n type=\"button\"\r\n (click)=\"editClicked.emit(row)\"\r\n [title]=\"'AbpUi::Edit' | abpLocalization\"\r\n >\r\n <i class=\"fa fa-edit\"></i>\r\n </button>\r\n <button\r\n class=\"btn btn-outline-danger\"\r\n type=\"button\"\r\n (click)=\"deleteClicked.emit(row)\"\r\n [title]=\"'AbpUi::Delete' | abpLocalization\"\r\n >\r\n <i class=\"fa fa-trash\"></i>\r\n </button>\r\n </div>\r\n</ng-template>\r\n\r\n@if (state.resourcePermissions().length > 0) {\r\n <abp-extensible-table\r\n [data]=\"state.resourcePermissions()\"\r\n [recordsTotal]=\"state.totalCount()\"\r\n [list]=\"list\"\r\n [actionsTemplate]=\"actionsTemplate\"\r\n actionsText=\"AbpUi::Actions\"\r\n />\r\n} @else {\r\n <div class=\"alert alert-info\">\r\n {{ 'AbpPermissionManagement::NoPermissionsAssigned' | abpLocalization }}\r\n </div>\r\n}\r\n" }]
}], ctorParameters: () => [], propDecorators: { addClicked: [{ type: i0.Output, args: ["addClicked"] }], editClicked: [{ type: i0.Output, args: ["editClicked"] }], deleteClicked: [{ type: i0.Output, args: ["deleteClicked"] }] } });
class ProviderKeySearchComponent {
constructor() {
this.state = inject(ResourcePermissionStateService);
this.service = inject(PermissionsService);
this.destroyRef = inject(DestroyRef);
this.resourceName = input.required(...(ngDevMode ? [{ debugName: "resourceName" }] : []));
this.searchFn = () => new Observable();
}
ngOnInit() {
this.searchFn = (filter) => this.loadProviderKeys(filter);
}
onItemSelected(item) {
// State is already updated via displayValue and selectedValue bindings
// This handler can be used for additional side effects if needed
}
loadProviderKeys(filter) {
const providerName = this.state.selectedProviderName();
if (!providerName) {
return new Observable(subscriber => {
subscriber.next([]);
subscriber.complete();
});
}
return this.service
.searchResourceProviderKey(this.resourceName(), providerName, filter, 1)
.pipe(map(res => (res.keys || []).map(k => ({
key: k.providerKey || '',
displayName: k.providerDisplayName || k.providerKey || '',
providerKey: k.providerKey || '',
providerDisplayName: k.providerDisplayName || undefined,
}))), takeUntilDestroyed(this.destroyRef));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ProviderKeySearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.9", type: ProviderKeySearchComponent, isStandalone: true, selector: "abp-provider-key-search", inputs: { resourceName: { classPropertyName: "resourceName", publicName: "resourceName", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<abp-lookup-search\r\n label=\"AbpPermissionManagement::SearchProviderKey\"\r\n placeholder=\"AbpPermissionManagement::SearchProviderKey\"\r\n [searchFn]=\"searchFn\"\r\n [displayValue]=\"state.searchFilter()\"\r\n (displayValueChange)=\"state.searchFilter.set($event)\"\r\n [selectedValue]=\"state.selectedProviderKey()\"\r\n (selectedValueChange)=\"state.selectedProviderKey.set($event)\"\r\n (itemSelected)=\"onItemSelected($event)\"\r\n/>\r\n", dependencies: [{ kind: "component", type: LookupSearchComponent, selector: "abp-lookup-search", inputs: ["label", "placeholder", "debounceTime", "minSearchLength", "displayKey", "valueKey", "disabled", "searchFn", "selectedValue", "displayValue"], outputs: ["selectedValueChange", "displayValueChange", "itemSelected", "searchChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ProviderKeySearchComponent, decorators: [{
type: Component,
args: [{ selector: 'abp-provider-key-search', imports: [LookupSearchComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<abp-lookup-search\r\n label=\"AbpPermissionManagement::SearchProviderKey\"\r\n placeholder=\"AbpPermissionManagement::SearchProviderKey\"\r\n [searchFn]=\"searchFn\"\r\n [displayValue]=\"state.searchFilter()\"\r\n (displayValueChange)=\"state.searchFilter.set($event)\"\r\n [selectedValue]=\"state.selectedProviderKey()\"\r\n (selectedValueChange)=\"state.selectedProviderKey.set($event)\"\r\n (itemSelected)=\"onItemSelected($event)\"\r\n/>\r\n" }]
}], propDecorators: { resourceName: [{ type: i0.Input, args: [{ isSignal: true, alias: "resourceName", required: true }] }] } });
class PermissionCheckboxListComponent {
constructor() {
this.state = inject(ResourcePermissionStateService);
this.permissions = input.required(...(ngDevMode ? [{ debugName: "permissions" }] : []));
this.idPrefix = input('default', ...(ngDevMode ? [{ debugName: "idPrefix" }] : []));
this.title = input('AbpPermissionManagement::ResourcePermissionPermissions', ...(ngDevMode ? [{ debugName: "title" }] : []));
this.showTitle = input(true, ...(ngDevMode ? [{ debugName: "showTitle" }] : []));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: PermissionCheckboxListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: PermissionCheckboxListComponent, isStandalone: true, selector: "abp-permission-checkbox-list", inputs: { permissions: { classPropertyName: "permissions", publicName: "permissions", isSignal: true, isRequired: true, transformFunction: null }, idPrefix: { classPropertyName: "idPrefix", publicName: "idPrefix", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showTitle: { classPropertyName: "showTitle", publicName: "showTitle", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"mb-3\">\r\n @if (showTitle()) {\r\n <h5>{{ title() | abpLocalization }}</h5>\r\n }\r\n <div class=\"form-check form-switch mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"grantAll-{{ idPrefix() }}\"\r\n [checked]=\"state.allPermissionsSelected()\"\r\n (change)=\"state.toggleAllPermissions(!state.allPermissionsSelected())\"\r\n />\r\n <label class=\"form-check-label\" for=\"grantAll-{{ idPrefix() }}\">\r\n {{ 'AbpPermissionManagement::GrantAllResourcePermissions' | abpLocalization }}\r\n </label>\r\n </div>\r\n <div class=\"abp-permission-list-container border rounded p-3\">\r\n @for (perm of permissions(); track perm.name) {\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"perm-{{ idPrefix() }}-{{ perm.name }}\"\r\n [checked]=\"state.isPermissionSelected(perm.name || '')\"\r\n (change)=\"state.togglePermission(perm.name || '')\"\r\n />\r\n <label class=\"form-check-label\" for=\"perm-{{ idPrefix() }}-{{ perm.name }}\">\r\n {{ perm.displayName }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".abp-permission-list-container{max-height:300px;overflow-y:auto}\n"], dependencies: [{ kind: "pipe", type: LocalizationPipe, name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: PermissionCheckboxListComponent, decorators: [{
type: Component,
args: [{ selector: 'abp-permission-checkbox-list', imports: [LocalizationPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"mb-3\">\r\n @if (showTitle()) {\r\n <h5>{{ title() | abpLocalization }}</h5>\r\n }\r\n <div class=\"form-check form-switch mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"grantAll-{{ idPrefix() }}\"\r\n [checked]=\"state.allPermissionsSelected()\"\r\n (change)=\"state.toggleAllPermissions(!state.allPermissionsSelected())\"\r\n />\r\n <label class=\"form-check-label\" for=\"grantAll-{{ idPrefix() }}\">\r\n {{ 'AbpPermissionManagement::GrantAllResourcePermissions' | abpLocalization }}\r\n </label>\r\n </div>\r\n <div class=\"abp-permission-list-container border rounded p-3\">\r\n @for (perm of permissions(); track perm.name) {\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"perm-{{ idPrefix() }}-{{ perm.name }}\"\r\n [checked]=\"state.isPermissionSelected(perm.name || '')\"\r\n (change)=\"state.togglePermission(perm.name || '')\"\r\n />\r\n <label class=\"form-check-label\" for=\"perm-{{ idPrefix() }}-{{ perm.name }}\">\r\n {{ perm.displayName }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".abp-permission-list-container{max-height:300px;overflow-y:auto}\n"] }]
}], propDecorators: { permissions: [{ type: i0.Input, args: [{ isSignal: true, alias: "permissions", required: true }] }], idPrefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "idPrefix", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], showTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTitle", required: false }] }] } });
class ResourcePermissionFormComponent {
constructor() {
this.state = inject(ResourcePermissionStateService);
this.eResourcePermissionViewModes = eResourcePermissionViewModes;
this.mode = input.required(...(ngDevMode ? [{ debugName: "mode" }] : []));
this.resourceName = input.required(...(ngDevMode ? [{ debugName: "resourceName" }] : []));
this.save = output();
this.cancel = output();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ResourcePermissionFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ResourcePermissionFormComponent, isStandalone: true, selector: "abp-resource-permission-form", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: true, transformFunction: null }, resourceName: { classPropertyName: "resourceName", publicName: "resourceName", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { save: "save", cancel: "cancel" }, ngImport: i0, template: "@if (mode() === eResourcePermissionViewModes.Add) {\r\n <div class=\"mb-3\">\r\n <label class=\"form-label fw-bold\">\r\n {{ 'AbpPermissionManagement::SelectProvider' | abpLocalization }}\r\n </label>\r\n <div class=\"mb-2\">\r\n @for (provider of state.providers(); track provider.name; let i = $index) {\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n [id]=\"'provider-' + i\"\r\n [value]=\"provider.name\"\r\n [checked]=\"state.selectedProviderName() === provider.name\"\r\n (change)=\"state.onProviderChange(provider.name || '')\"\r\n />\r\n <label class=\"form-check-label\" [for]=\"'provider-' + i\">\r\n {{ provider.displayName }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n\r\n <abp-provider-key-search [resourceName]=\"resourceName()\" />\r\n </div>\r\n\r\n <abp-permission-checkbox-list [permissions]=\"state.permissionDefinitions()\" idPrefix=\"add\" />\r\n} @else {\r\n <div class=\"mb-3\" id=\"permissionList\">\r\n <h4>{{ 'AbpPermissionManagement::Permissions' | abpLocalization }}</h4>\r\n <abp-permission-checkbox-list\r\n [permissions]=\"state.permissionsWithProvider()\"\r\n idPrefix=\"edit\"\r\n [showTitle]=\"false\"\r\n />\r\n </div>\r\n}\r\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ProviderKeySearchComponent, selector: "abp-provider-key-search", inputs: ["resourceName"] }, { kind: "component", type: PermissionCheckboxListComponent, selector: "abp-permission-checkbox-list", inputs: ["permissions", "idPrefix", "title", "showTitle"] }, { kind: "pipe", type: LocalizationPipe, name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ResourcePermissionFormComponent, decorators: [{
type: Component,
args: [{ selector: 'abp-resource-permission-form', imports: [
FormsModule,
LocalizationPipe,
ProviderKeySearchComponent,
PermissionCheckboxListComponent,
], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (mode() === eResourcePermissionViewModes.Add) {\r\n <div class=\"mb-3\">\r\n <label class=\"form-label fw-bold\">\r\n {{ 'AbpPermissionManagement::SelectProvider' | abpLocalization }}\r\n </label>\r\n <div class=\"mb-2\">\r\n @for (provider of state.providers(); track provider.name; let i = $index) {\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n [id]=\"'provider-' + i\"\r\n [value]=\"provider.name\"\r\n [checked]=\"state.selectedProviderName() === provider.name\"\r\n (change)=\"state.onProviderChange(provider.name || '')\"\r\n />\r\n <label class=\"form-check-label\" [for]=\"'provider-' + i\">\r\n {{ provider.displayName }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n\r\n <abp-provider-key-search [resourceName]=\"resourceName()\" />\r\n </div>\r\n\r\n <abp-permission-checkbox-list [permissions]=\"state.permissionDefinitions()\" idPrefix=\"add\" />\r\n} @else {\r\n <div class=\"mb-3\" id=\"permissionList\">\r\n <h4>{{ 'AbpPermissionManagement::Permissions' | abpLocalization }}</h4>\r\n <abp-permission-checkbox-list\r\n [permissions]=\"state.permissionsWithProvider()\"\r\n idPrefix=\"edit\"\r\n [showTitle]=\"false\"\r\n />\r\n </div>\r\n}\r\n" }]
}], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: true }] }], resourceName: [{ type: i0.Input, args: [{ isSignal: true, alias: "resourceName", required: true }] }], save: [{ type: i0.Output, args: ["save"] }], cancel: [{ type: i0.Output, args: ["cancel"] }] } });
const DEFAULT_MAX_RESULT_COUNT = 10;
class ResourcePermissionManagementComponent {
constructor() {
this.eResourcePermissionViewModes = eResourcePermissionViewModes;
this.service = inject(PermissionsService);
this.toasterService = inject(ToasterService);
this.confirmationService = inject(ConfirmationService);
this.state = inject(ResourcePermissionStateService);
this.list = inject(ListService);
this.resourceName = input.required(...(ngDevMode ? [{ debugName: "resourceName" }] : []));
this.resourceKey = input.required(...(ngDevMode ? [{ debugName: "resourceKey" }] : []));
this.resourceDisplayName = input(...(ngDevMode ? [undefined, { debugName: "resourceDisplayName" }] : []));
this.visible = model(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
this.previousVisible = signal(false, ...(ngDevMode ? [{ debugName: "previousVisible" }] : []));
effect(() => {
const resourceName = this.resourceName();
const resourceKey = this.resourceKey();
const resourceDisplayName = this.resourceDisplayName();
untracked(() => {
this.state.resourceName.set(resourceName);
this.state.resourceKey.set(resourceKey);
this.state.resourceDisplayName.set(resourceDisplayName);
});
});
effect(() => {
const isVisible = this.visible();
const wasVisible = this.previousVisible();
if (isVisible && !wasVisible) {
this.openModal();
}
else if (!isVisible && wasVisible) {
this.state.reset();
}
untracked(() => this.previousVisible.set(isVisible));
});
}
ngOnInit() {
this.list.maxResultCount = DEFAULT_MAX_RESULT_COUNT;
this.list
.hookToQuery(query => {
const allData = this.state.allResourcePermissions();
const skipCount = query.skipCount || 0;
const maxResultCount = query.maxResultCount || DEFAULT_MAX_RESULT_COUNT;
const paginatedData = allData.slice(skipCount, skipCount + maxResultCount);
return of({
items: paginatedData,
totalCount: allData.length,
});
})
.subscribe(result => {
this.state.resourcePermissions.set(result.items);
this.state.totalCount.set(result.totalCount);
});
}
openModal() {
this.state.modalBusy.set(true);
this.service
.getResource(this.resourceName(), this.resourceKey())
.pipe(switchMap$1(permRes => {
this.state.setResourceData(permRes.permissions || []);
this.list.get();
return this.service.getResourceProviderKeyLookupServices(this.resourceName());
}), switchMap$1(providerRes => {
this.state.setProviders(providerRes.providers || []);
return this.service.getResourceDefinitions(this.resourceName());
}), finalize$1(() => this.state.modalBusy.set(false)))
.subscribe({
next: defRes => {
this.state.setDefinitions(defRes.permissions || []);
},
error: () => {
this.toasterService.error('AbpPermissionManagement::ErrorLoadingPermissions');
},
});
}
onAddClicked() {
this.state.goToAddMode();
}
onEditClicked(grant) {
this.state.prepareEditMode(grant);
this.state.modalBusy.set(true);
this.service
.getResourceByProvider(this.resourceName(), this.resourceKey(), grant.providerName || '', grant.providerKey || '')
.pipe(finalize$1(() => this.state.modalBusy.set(false)))
.subscribe({
next: res => {
this.state.setEditModePermissions(res.permissions || []);
},
});
}
onDeleteClicked(grant) {
this.confirmationService
.warn('AbpPermissionManagement::ResourcePermissionDeletionConfirmationMessage', 'AbpPermissionManagement::AreYouSure', {
messageLocalizationParams: [grant.providerKey || ''],
})
.subscribe((status) => {
if (status === Confirmation.Status.confirm) {
this.state.modalBusy.set(true);
this.service
.deleteResource(this.resourceName(), this.resourceKey(), grant.providerName || '', grant.providerKey || '')
.pipe(switchMap$1(() => this.service.getResource(this.resourceName(), this.resourceKey())), finalize$1(() => this.state.modalBusy.set(false)))
.subscribe({
next: res => {
this.state.setResourceData(res.permissions || []);
this.list.get();
this.toasterService.success('AbpUi::DeletedSuccessfully');
},
});
}
});
}
savePermission() {
const isEdit = this.state.isEditMode();
const providerName = isEdit ? this.state.editProviderName() : this.state.selectedProviderName();
const providerKey = isEdit ? this.state.editProviderKey() : this.state.selectedProviderKey();
if (!isEdit && !this.state.canSave()) {
this.toasterService.warn('AbpPermissionManagement::PleaseSelectProviderAndPermissions');
return;
}
this.state.modalBusy.set(true);
this.service
.updateResource(this.resourceName(), this.resourceKey(), {
providerName,
providerKey,
permissions: this.state.selectedPermissions(),
})
.pipe(switchMap$1(() => this.service.getResource(this.resourceName(), this.resourceKey())), finalize$1(() => this.state.modalBusy.set(false)))
.subscribe({
next: res => {
this.state.setResourceData(res.permissions || []);
this.list.get();
this.toasterService.success('AbpUi::SavedSuccessfully');
this.state.goToListMode();
},
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ResourcePermissionManagementComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ResourcePermissionManagementComponent, isStandalone: true, selector: "abp-resource-permission-management", inputs: { resourceName: { classPropertyName: "resourceName", publicName: "resourceName", isSignal: true, isRequired: true, transformFunction: null }, resourceKey: { classPropertyName: "resourceKey", publicName: "resourceKey", isSignal: true, isRequired: true, transformFunction: null }, resourceDisplayName: { classPropertyName: "resourceDisplayName", publicName: "resourceDisplayName", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange" }, providers: [ResourcePermissionStateService, ListService], exportAs: ["abpResourcePermissionManagement"], ngImport: i0, template: "<abp-modal\r\n [(visible)]=\"visible\"\r\n [busy]=\"state.modalBusy()\"\r\n [options]=\"{ size: 'xl', scrollable: false }\"\r\n>\r\n <ng-template #abpHeader>\r\n <h5 class=\"modal-title\">\r\n @switch (state.viewMode()) {\r\n @case (eResourcePermissionViewModes.Edit) {\r\n {{ 'AbpPermissionManagement::UpdatePermission' | abpLocalization }}\r\n }\r\n @case (eResourcePermissionViewModes.Add) {\r\n {{ 'AbpPermissionManagement::AddResourcePermission' | abpLocalization }}\r\n }\r\n @default {\r\n {{ 'AbpPermissionManagement::ResourcePermissions' | abpLocalization }}\r\n @if (resourceDisplayName()) {\r\n - {{ resourceDisplayName() }}\r\n }\r\n }\r\n }\r\n </h5>\r\n </ng-template>\r\n\r\n <ng-template #abpBody>\r\n @if (!state.hasResourcePermission() || !state.hasProviderKeyLookupService()) {\r\n <div class=\"alert alert-warning\" role=\"alert\">\r\n @if (!state.hasResourcePermission()) {\r\n {{ 'AbpPermissionManagement::NoResourcePermissionFound' | abpLocalization }}\r\n } @else {\r\n {{ 'AbpPermissionManagement::NoResourceProviderKeyLookupServiceFound' | abpLocalization }}\r\n }\r\n </div>\r\n } @else {\r\n @switch (state.viewMode()) {\r\n @case (eResourcePermissionViewModes.List) {\r\n <abp-resource-permission-list\r\n (addClicked)=\"onAddClicked()\"\r\n (editClicked)=\"onEditClicked($event)\"\r\n (deleteClicked)=\"onDeleteClicked($event)\"\r\n />\r\n }\r\n @case (eResourcePermissionViewModes.Add) {\r\n <abp-resource-permission-form mode=\"add\" [resourceName]=\"resourceName()\" />\r\n }\r\n @case (eResourcePermissionViewModes.Edit) {\r\n <abp-resource-permission-form mode=\"edit\" [resourceName]=\"resourceName()\" />\r\n }\r\n }\r\n }\r\n </ng-template>\r\n\r\n <ng-template #abpFooter>\r\n @if (state.isListMode()) {\r\n <button type=\"button\" class=\"btn btn-outline-primary\" abpClose>\r\n {{ 'AbpUi::Close' | abpLocalization }}\r\n </button>\r\n } @else {\r\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"state.goToListMode()\">\r\n {{ 'AbpUi::Cancel' | abpLocalization }}\r\n </button>\r\n <abp-button iconClass=\"fa fa-check\" (click)=\"savePermission()\">\r\n {{ 'AbpUi::Save' | abpLocalization }}\r\n </abp-button>\r\n }\r\n </ng-template>\r\n</abp-modal>\r\n", dependencies: [{ kind: "component", type: ModalComponent, selector: "abp-modal", inputs: ["visible", "busy", "options", "suppressUnsavedChangesWarning"], outputs: ["visibleChange", "init", "appear", "disappear"] }, { kind: "component", type: ButtonComponent, selector: "abp-button", inputs: ["buttonId", "buttonClass", "buttonType", "formName", "iconClass", "loading", "disabled", "attributes"], outputs: ["click", "focus", "blur", "abpClick", "abpFocus", "abpBlur"] }, { kind: "directive", type: ModalCloseDirective, selector: "[abpClose]" }, { kind: "component", type: ResourcePermissionListComponent, selector: "abp-resource-permission-list", outputs: ["addClicked", "editClicked", "deleteClicked"] }, { kind: "component", type: ResourcePermissionFormComponent, selector: "abp-resource-permission-form", inputs: ["mode", "resourceName"], outputs: ["save", "cancel"] }, { kind: "pipe", type: LocalizationPipe, name: "abpLocalization" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ResourcePermissionManagementComponent, decorators: [{
type: Component,
args: [{ selector: 'abp-resource-permission-management', exportAs: 'abpResourcePermissionManagement', providers: [ResourcePermissionStateService, ListService], imports: [
ModalComponent,
LocalizationPipe,
ButtonComponent,
ModalCloseDirective,
ResourcePermissionListComponent,
ResourcePermissionFormComponent,
], template: "<abp-modal\r\n [(visible)]=\"visible\"\r\n [busy]=\"state.modalBusy()\"\r\n [options]=\"{ size: 'xl', scrollable: false }\"\r\n>\r\n <ng-template #abpHeader>\r\n <h5 class=\"modal-title\">\r\n @switch (state.viewMode()) {\r\n @case (eResourcePermissionViewModes.Edit) {\r\n {{ 'AbpPermissionManagement::UpdatePermission' | abpLocalization }}\r\n }\r\n @case (eResourcePermissionViewModes.Add) {\r\n {{ 'AbpPermissionManagement::AddResourcePermission' | abpLocalization }}\r\n }\r\n @default {\r\n {{ 'AbpPermissionManagement::ResourcePermissions' | abpLocalization }}\r\n @if (resourceDisplayName()) {\r\n - {{ resourceDisplayName() }}\r\n }\r\n }\r\n }\r\n </h5>\r\n </ng-template>\r\n\r\n <ng-template #abpBody>\r\n @if (!state.hasResourcePermission() || !state.hasProviderKeyLookupService()) {\r\n <div class=\"alert alert-warning\" role=\"alert\">\r\n @if (!state.hasResourcePermission()) {\r\n {{ 'AbpPermissionManagement::NoResourcePermissionFound' | abpLocalization }}\r\n } @else {\r\n {{ 'AbpPermissionManagement::NoResourceProviderKeyLookupServiceFound' | abpLocalization }}\r\n }\r\n </div>\r\n } @else {\r\n @switch (state.viewMode()) {\r\n @case (eResourcePermissionViewModes.List) {\r\n <abp-resource-permission-list\r\n (addClicked)=\"onAddClicked()\"\r\n (editClicked)=\"onEditClicked($event)\"\r\n (deleteClicked)=\"onDeleteClicked($event)\"\r\n />\r\n }\r\n @case (eResourcePermissionViewModes.Add) {\r\n <abp-resource-permission-form mode=\"add\" [resourceName]=\"resourceName()\" />\r\n }\r\n @case (eResourcePermissionViewModes.Edit) {\r\n <abp-resource-permission-form mode=\"edit\" [resourceName]=\"resourceName()\" />\r\n }\r\n }\r\n }\r\n </ng-template>\r\n\r\n <ng-template #abpFooter>\r\n @if (state.isListMode()) {\r\n <button type=\"button\" class=\"btn btn-outline-primary\" abpClose>\r\n {{ 'AbpUi::Close' | abpLocalization }}\r\n </button>\r\n } @else {\r\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"state.goToListMode()\">\r\n {{ 'AbpUi::Cancel' | abpLocalization }}\r\n </button>\r\n <abp-button iconClass=\"fa fa-check\" (click)=\"savePermission()\">\r\n {{ 'AbpUi::Save' | abpLocalization }}\r\n </abp-button>\r\n }\r\n </ng-template>\r\n</abp-modal>\r\n" }]
}], ctorParameters: () => [], propDecorators: { resourceName: [{ type: i0.Input, args: [{ isSignal: true, alias: "resourceName", required: true }] }], resourceKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "resourceKey", required: true }] }], resourceDisplayName: [{ type: i0.Input, args: [{ isSignal: true, alias: "resourceDisplayName", required: false }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }] } });
class PermissionManagementModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: PermissionManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.0.9", ngImport: i0, type: PermissionManagementModule, imports: [PermissionManagementComponent], exports: [PermissionManagementComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: PermissionManagementModule, imports: [PermissionManagementComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: PermissionManagementModule, decorators: [{
type: NgModule,
args: [{
declarations: [],
imports: [PermissionManagementComponent],
exports: [PermissionManagementComponent],
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { PermissionCheckboxListComponent, PermissionManagementComponent, PermissionManagementModule, ProviderKeySearchComponent, ResourcePermissionFormComponent, ResourcePermissionListComponent, ResourcePermissionManagementComponent };
//# sourceMappingURL=abp-ng.permission-management.mjs.map