|
|
@ -1,4 +1,20 @@ |
|
|
|
|
|
import { |
|
|
|
|
|
ChangeDetectionStrategy, |
|
|
|
|
|
Component, |
|
|
|
|
|
computed, |
|
|
|
|
|
DOCUMENT, |
|
|
|
|
|
inject, |
|
|
|
|
|
input, |
|
|
|
|
|
output, |
|
|
|
|
|
signal, |
|
|
|
|
|
TrackByFunction, |
|
|
|
|
|
} from '@angular/core'; |
|
|
import { NgStyle } from '@angular/common'; |
|
|
import { NgStyle } from '@angular/common'; |
|
|
|
|
|
import { FormsModule } from '@angular/forms'; |
|
|
|
|
|
import { Tabs, TabList, Tab, TabPanel, TabContent } from '@angular/aria/tabs'; |
|
|
|
|
|
import { of } from 'rxjs'; |
|
|
|
|
|
import { finalize, switchMap, tap } from 'rxjs/operators'; |
|
|
|
|
|
|
|
|
import { ConfigStateService, CurrentUserDto, LocalizationPipe } from '@abp/ng.core'; |
|
|
import { ConfigStateService, CurrentUserDto, LocalizationPipe } from '@abp/ng.core'; |
|
|
import { |
|
|
import { |
|
|
ButtonComponent, |
|
|
ButtonComponent, |
|
|
@ -15,27 +31,6 @@ import { |
|
|
ProviderInfoDto, |
|
|
ProviderInfoDto, |
|
|
UpdatePermissionDto, |
|
|
UpdatePermissionDto, |
|
|
} from '@abp/ng.permission-management/proxy'; |
|
|
} from '@abp/ng.permission-management/proxy'; |
|
|
import { |
|
|
|
|
|
afterNextRender, |
|
|
|
|
|
Component, |
|
|
|
|
|
computed, |
|
|
|
|
|
DOCUMENT, |
|
|
|
|
|
ElementRef, |
|
|
|
|
|
inject, |
|
|
|
|
|
Injector, |
|
|
|
|
|
input, |
|
|
|
|
|
output, |
|
|
|
|
|
signal, |
|
|
|
|
|
TrackByFunction, |
|
|
|
|
|
viewChildren, |
|
|
|
|
|
} from '@angular/core'; |
|
|
|
|
|
import { of } from 'rxjs'; |
|
|
|
|
|
import { finalize, switchMap, tap } from 'rxjs/operators'; |
|
|
|
|
|
import { PermissionManagement } from '../models'; |
|
|
|
|
|
|
|
|
|
|
|
import { FormsModule } from '@angular/forms'; |
|
|
|
|
|
|
|
|
|
|
|
import { Tabs, TabList, Tab, TabPanel, TabContent } from '@angular/aria/tabs'; |
|
|
|
|
|
|
|
|
|
|
|
type PermissionWithStyle = PermissionGrantInfoDto & { |
|
|
type PermissionWithStyle = PermissionGrantInfoDto & { |
|
|
style: Record<string, number>; |
|
|
style: Record<string, number>; |
|
|
@ -45,7 +40,13 @@ type PermissionWithGroupName = PermissionGrantInfoDto & { |
|
|
groupName: string; |
|
|
groupName: string; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
type SelectAllCheckboxState = { |
|
|
|
|
|
checked: boolean; |
|
|
|
|
|
indeterminate: boolean; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@Component({ |
|
|
@Component({ |
|
|
|
|
|
changeDetection: ChangeDetectionStrategy.OnPush, |
|
|
selector: 'abp-permission-management', |
|
|
selector: 'abp-permission-management', |
|
|
templateUrl: './permission-management.component.html', |
|
|
templateUrl: './permission-management.component.html', |
|
|
exportAs: 'abpPermissionManagement', |
|
|
exportAs: 'abpPermissionManagement', |
|
|
@ -114,10 +115,8 @@ export class PermissionManagementComponent { |
|
|
protected readonly service = inject(PermissionsService); |
|
|
protected readonly service = inject(PermissionsService); |
|
|
protected readonly configState = inject(ConfigStateService); |
|
|
protected readonly configState = inject(ConfigStateService); |
|
|
protected readonly toasterService = inject(ToasterService); |
|
|
protected readonly toasterService = inject(ToasterService); |
|
|
private readonly injector = inject(Injector); |
|
|
|
|
|
private document = inject(DOCUMENT); |
|
|
private document = inject(DOCUMENT); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
readonly providerNameInput = input('', { alias: 'providerName' }); |
|
|
readonly providerNameInput = input('', { alias: 'providerName' }); |
|
|
readonly providerKeyInput = input('', { alias: 'providerKey' }); |
|
|
readonly providerKeyInput = input('', { alias: 'providerKey' }); |
|
|
readonly hideBadgesInput = input(false, { alias: 'hideBadges' }); |
|
|
readonly hideBadgesInput = input(false, { alias: 'hideBadges' }); |
|
|
@ -127,9 +126,10 @@ export class PermissionManagementComponent { |
|
|
readonly visibleChange = output<boolean>(); |
|
|
readonly visibleChange = output<boolean>(); |
|
|
|
|
|
|
|
|
protected readonly modalVisible = signal(false); |
|
|
protected readonly modalVisible = signal(false); |
|
|
|
|
|
protected readonly modalBusy = signal(false); |
|
|
|
|
|
protected readonly filter = signal<string>(''); |
|
|
|
|
|
|
|
|
private isOpening = false; |
|
|
private isOpening = false; |
|
|
|
|
|
|
|
|
private isClosingModal = false; |
|
|
private isClosingModal = false; |
|
|
|
|
|
|
|
|
// Backward-compatible getters/setters for ReplaceableTemplateDirective.
|
|
|
// Backward-compatible getters/setters for ReplaceableTemplateDirective.
|
|
|
@ -157,30 +157,48 @@ export class PermissionManagementComponent { |
|
|
this._hideBadgesOverride = value; |
|
|
this._hideBadgesOverride = value; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
selectAllInThisTabsRef = viewChildren<ElementRef<HTMLInputElement>>('selectAllInThisTabsRef'); |
|
|
|
|
|
selectAllInAllTabsRef = viewChildren<ElementRef<HTMLInputElement>>('selectAllInAllTabsRef'); |
|
|
|
|
|
|
|
|
|
|
|
data: GetPermissionListResultDto = { groups: [], entityDisplayName: '' }; |
|
|
data: GetPermissionListResultDto = { groups: [], entityDisplayName: '' }; |
|
|
|
|
|
|
|
|
selectedGroup?: PermissionGroupDto | null; |
|
|
private readonly permissionsState = signal<PermissionWithGroupName[]>([]); |
|
|
|
|
|
private readonly selectedGroupState = signal<PermissionGroupDto | null>(null); |
|
|
|
|
|
private readonly permissionGroupSignal = signal<PermissionGroupDto[]>([]); |
|
|
|
|
|
|
|
|
permissions: PermissionWithGroupName[] = []; |
|
|
protected readonly selectedGroupPermissions = computed(() => { |
|
|
|
|
|
const group = this.selectedGroupState(); |
|
|
selectThisTab = false; |
|
|
if (!group) { |
|
|
|
|
|
return [] as PermissionWithStyle[]; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
selectAllTab = false; |
|
|
const margin = `margin-${ |
|
|
|
|
|
(this.document.body?.dir as LocaleDirection) === 'rtl' ? 'right' : 'left' |
|
|
|
|
|
}.px`;
|
|
|
|
|
|
|
|
|
disableSelectAllTab = false; |
|
|
const groupPermissions = |
|
|
|
|
|
this.permissionGroupSignal().find(item => item.name === group.name)?.permissions || []; |
|
|
|
|
|
const permissions = this.permissionsState(); |
|
|
|
|
|
|
|
|
disabledSelectAllInAllTabs = false; |
|
|
return groupPermissions.map(permission => ({ |
|
|
|
|
|
...permission, |
|
|
|
|
|
style: { [margin]: findMargin(groupPermissions, permission) }, |
|
|
|
|
|
isGranted: (permissions.find(per => per.name === permission.name) || {}).isGranted, |
|
|
|
|
|
})) as PermissionWithStyle[]; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
modalBusy = false; |
|
|
protected readonly selectThisTabState = computed(() => |
|
|
|
|
|
getSelectAllCheckboxState(this.selectedGroupPermissions(), this.providerName), |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
filter = signal<string>(''); |
|
|
protected readonly selectAllTabState = computed(() => |
|
|
|
|
|
getSelectAllCheckboxState(this.permissionsState(), this.providerName), |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
selectedGroupPermissions: PermissionWithStyle[] = []; |
|
|
// Disabled state is based on the API snapshot (not live edits) so select-all stays toggleable.
|
|
|
|
|
|
protected readonly disableSelectAllTab = computed(() => |
|
|
|
|
|
isSelectAllDisabled(this.selectedGroupState()?.permissions, this.providerName), |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
permissionGroupSignal = signal<PermissionGroupDto[]>([]); |
|
|
private readonly disabledSelectAllInAllTabsState = signal(false); |
|
|
|
|
|
protected readonly disabledSelectAllInAllTabs = this.disabledSelectAllInAllTabsState.asReadonly(); |
|
|
|
|
|
|
|
|
permissionGroups = computed(() => { |
|
|
permissionGroups = computed(() => { |
|
|
const search = this.filter().toLowerCase().trim(); |
|
|
const search = this.filter().toLowerCase().trim(); |
|
|
@ -200,7 +218,7 @@ export class PermissionManagementComponent { |
|
|
|
|
|
|
|
|
trackByFn: TrackByFunction<PermissionGroupDto> = (_, item) => item.name; |
|
|
trackByFn: TrackByFunction<PermissionGroupDto> = (_, item) => item.name; |
|
|
|
|
|
|
|
|
// Backward-compatible getter/setter for ReplaceableTemplateDirective.
|
|
|
// Backward-compatible getters/setters for ReplaceableTemplateDirective.
|
|
|
get visible(): boolean { |
|
|
get visible(): boolean { |
|
|
return this.modalVisible(); |
|
|
return this.modalVisible(); |
|
|
} |
|
|
} |
|
|
@ -221,6 +239,26 @@ export class PermissionManagementComponent { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
get permissions(): PermissionWithGroupName[] { |
|
|
|
|
|
return this.permissionsState(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
set permissions(value: PermissionWithGroupName[]) { |
|
|
|
|
|
this.permissionsState.set(value); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
get selectedGroup(): PermissionGroupDto | null | undefined { |
|
|
|
|
|
return this.selectedGroupState(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
get selectThisTab(): boolean { |
|
|
|
|
|
return this.selectThisTabState().checked; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
get selectAllTab(): boolean { |
|
|
|
|
|
return this.selectAllTabState().checked; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
onModalVisibleChange(value: boolean) { |
|
|
onModalVisibleChange(value: boolean) { |
|
|
this.visibleChange.emit(value); |
|
|
this.visibleChange.emit(value); |
|
|
} |
|
|
} |
|
|
@ -246,9 +284,6 @@ export class PermissionManagementComponent { |
|
|
.subscribe(() => { |
|
|
.subscribe(() => { |
|
|
this.modalVisible.set(true); |
|
|
this.modalVisible.set(true); |
|
|
this.visibleChange.emit(true); |
|
|
this.visibleChange.emit(true); |
|
|
afterNextRender(() => { |
|
|
|
|
|
this.initModal(); |
|
|
|
|
|
}, { injector: this.injector }); |
|
|
|
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -265,45 +300,16 @@ export class PermissionManagementComponent { |
|
|
private resetModalState() { |
|
|
private resetModalState() { |
|
|
this.setSelectedGroup(null); |
|
|
this.setSelectedGroup(null); |
|
|
this.filter.set(''); |
|
|
this.filter.set(''); |
|
|
this.selectAllTab = false; |
|
|
this.disabledSelectAllInAllTabsState.set(false); |
|
|
this.selectThisTab = false; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
getChecked(name: string) { |
|
|
getChecked(name: string) { |
|
|
return (this.permissions.find(per => per.name === name) || { isGranted: false }).isGranted; |
|
|
return (this.permissionsState().find(per => per.name === name) || { isGranted: false }) |
|
|
|
|
|
.isGranted; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
setSelectedGroup(group: PermissionGroupDto) { |
|
|
setSelectedGroup(group: PermissionGroupDto | null) { |
|
|
this.selectedGroup = group; |
|
|
this.selectedGroupState.set(group); |
|
|
if (!this.selectedGroup) { |
|
|
|
|
|
this.selectedGroupPermissions = []; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const margin = `margin-${ |
|
|
|
|
|
(this.document.body?.dir as LocaleDirection) === '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: PermissionGrantInfoDto[]) { |
|
|
|
|
|
if (permissions.length) { |
|
|
|
|
|
this.disableSelectAllTab = permissions.every( |
|
|
|
|
|
permission => |
|
|
|
|
|
permission.isGranted && |
|
|
|
|
|
permission.grantedProviders?.every(p => p.providerName !== this.providerName), |
|
|
|
|
|
); |
|
|
|
|
|
} else { |
|
|
|
|
|
this.disableSelectAllTab = false; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
isGrantedByOtherProviderName(grantedProviders?: ProviderInfoDto[]): boolean { |
|
|
isGrantedByOtherProviderName(grantedProviders?: ProviderInfoDto[]): boolean { |
|
|
@ -319,178 +325,126 @@ export class PermissionManagementComponent { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
this.setSelectedGroup(this.selectedGroup); |
|
|
|
|
|
setTimeout(() => { |
|
|
setTimeout(() => { |
|
|
this.updatePermissionStatus(clickedPermission); |
|
|
this.updatePermissionStatus(clickedPermission); |
|
|
this.updateSelectedGroupPermissions(clickedPermission); |
|
|
|
|
|
this.setParentClicked(clickedPermission); |
|
|
this.setParentClicked(clickedPermission); |
|
|
this.setTabCheckboxState(); |
|
|
|
|
|
this.setGrantCheckboxState(); |
|
|
|
|
|
}, 0); |
|
|
}, 0); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
updatePermissionStatus(clickedPermission: PermissionGrantInfoDto) { |
|
|
updatePermissionStatus(clickedPermission: PermissionGrantInfoDto) { |
|
|
this.permissions = this.permissions.map(permission => { |
|
|
this.permissionsState.update(permissions => |
|
|
const isExactMatch = clickedPermission.name == permission.name; |
|
|
permissions.map(permission => { |
|
|
const isParentOfPermission = clickedPermission.parentName === permission.name; |
|
|
const isExactMatch = clickedPermission.name == permission.name; |
|
|
const isChildOfPermission = clickedPermission.name === permission.parentName; |
|
|
const isParentOfPermission = clickedPermission.parentName === permission.name; |
|
|
|
|
|
const isChildOfPermission = clickedPermission.name === permission.parentName; |
|
|
if (isExactMatch) { |
|
|
|
|
|
return { ...permission, isGranted: !permission.isGranted }; |
|
|
if (isExactMatch) { |
|
|
} |
|
|
return { ...permission, isGranted: !permission.isGranted }; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (isChildOfPermission && permission.isGranted) { |
|
|
if (isChildOfPermission && permission.isGranted) { |
|
|
return { ...permission, isGranted: false }; |
|
|
return { ...permission, isGranted: false }; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (isParentOfPermission && !permission.isGranted) { |
|
|
if (isParentOfPermission && !permission.isGranted) { |
|
|
return { ...permission, isGranted: true }; |
|
|
return { ...permission, isGranted: true }; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return permission; |
|
|
return permission; |
|
|
}); |
|
|
}), |
|
|
|
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
setParentClicked(clickedPermission: PermissionGrantInfoDto) { |
|
|
setParentClicked(clickedPermission: PermissionGrantInfoDto) { |
|
|
if (clickedPermission.parentName) { |
|
|
if (clickedPermission.parentName) { |
|
|
const parentPermissions = findParentPermissions(this.permissions, clickedPermission); |
|
|
const parentPermissions = findParentPermissions(this.permissionsState(), clickedPermission); |
|
|
if (parentPermissions.length > 0) { |
|
|
if (parentPermissions.length > 0) { |
|
|
const parentNames = new Set(parentPermissions.map(parent => parent.name)); |
|
|
const parentNames = new Set(parentPermissions.map(parent => parent.name)); |
|
|
|
|
|
|
|
|
this.permissions = this.permissions.map(per => { |
|
|
this.permissionsState.update(permissions => |
|
|
let updatedIsGranted = per.isGranted; |
|
|
permissions.map(per => { |
|
|
|
|
|
let updatedIsGranted = per.isGranted; |
|
|
|
|
|
|
|
|
if (per.parentName === clickedPermission.name && !clickedPermission.isGranted) { |
|
|
if (per.parentName === clickedPermission.name && !clickedPermission.isGranted) { |
|
|
updatedIsGranted = false; |
|
|
updatedIsGranted = false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (parentNames.has(per.name)) { |
|
|
if (parentNames.has(per.name)) { |
|
|
updatedIsGranted = true; |
|
|
updatedIsGranted = true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return { ...per, isGranted: updatedIsGranted }; |
|
|
return { ...per, isGranted: updatedIsGranted }; |
|
|
}); |
|
|
}), |
|
|
|
|
|
); |
|
|
} |
|
|
} |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
this.permissions = this.permissions.map(per => { |
|
|
this.permissionsState.update(permissions => |
|
|
const parents = findParentPermissions(this.permissions, per); |
|
|
permissions.map(per => { |
|
|
if (parents.length > 0) { |
|
|
const parents = findParentPermissions(permissions, per); |
|
|
const rootParent = parents[parents.length - 1]; |
|
|
if (parents.length > 0) { |
|
|
|
|
|
const rootParent = parents[parents.length - 1]; |
|
|
|
|
|
|
|
|
if (rootParent.name === clickedPermission.name && !rootParent.isGranted) { |
|
|
if (rootParent.name === clickedPermission.name && !rootParent.isGranted) { |
|
|
return { ...per, isGranted: false }; |
|
|
return { ...per, isGranted: false }; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return per; |
|
|
return per; |
|
|
}), |
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
updateSelectedGroupPermissions(clickedPermissions: PermissionGrantInfoDto) { |
|
|
|
|
|
this.selectedGroupPermissions = this.selectedGroupPermissions.map(per => { |
|
|
|
|
|
if (per.name === clickedPermissions.name) { |
|
|
|
|
|
per.isGranted = !per.isGranted; |
|
|
|
|
|
} |
|
|
|
|
|
return per; |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
setTabCheckboxState() { |
|
|
|
|
|
const providerName = this.providerName; |
|
|
|
|
|
const selectablePermissions = this.selectedGroupPermissions.filter(per => |
|
|
|
|
|
(per.grantedProviders ?? []).every(p => p.providerName === providerName), |
|
|
|
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
const selectedPermissions = selectablePermissions.filter(per => per.isGranted); |
|
|
|
|
|
const element = this.document.querySelector( |
|
|
|
|
|
'#select-all-in-this-tabs', |
|
|
|
|
|
) as HTMLInputElement | null; |
|
|
|
|
|
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() { |
|
|
onSelectThisTabChange(event: Event) { |
|
|
const providerName = this.providerName; |
|
|
if (this.disableSelectAllTab()) { |
|
|
const selectablePermissions = this.permissions.filter(per => |
|
|
|
|
|
(per.grantedProviders ?? []).every(p => p.providerName === providerName), |
|
|
|
|
|
); |
|
|
|
|
|
const selectedAllPermissions = selectablePermissions.filter(per => per.isGranted); |
|
|
|
|
|
const checkboxElement = this.document.querySelector( |
|
|
|
|
|
'#select-all-in-all-tabs', |
|
|
|
|
|
) as HTMLInputElement | null; |
|
|
|
|
|
|
|
|
|
|
|
if (!checkboxElement) { |
|
|
|
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (selectedAllPermissions.length === selectablePermissions.length) { |
|
|
const state = this.selectThisTabState(); |
|
|
checkboxElement.indeterminate = false; |
|
|
const checked = !state.checked || state.indeterminate; |
|
|
this.selectAllTab = true; |
|
|
|
|
|
} else if (selectedAllPermissions.length === 0) { |
|
|
|
|
|
checkboxElement.indeterminate = false; |
|
|
|
|
|
this.selectAllTab = false; |
|
|
|
|
|
} else { |
|
|
|
|
|
checkboxElement.indeterminate = true; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
onSelectThisTabChange(event: Event) { |
|
|
this.permissionsState.update(permissions => { |
|
|
const checked = (event.target as HTMLInputElement).checked; |
|
|
let updatedPermissions = [...permissions]; |
|
|
this.selectThisTab = checked; |
|
|
|
|
|
|
|
|
|
|
|
this.selectedGroupPermissions.forEach(permission => { |
|
|
this.selectedGroupPermissions().forEach(permission => { |
|
|
if (permission.isGranted && this.isGrantedByOtherProviderName(permission.grantedProviders)) { |
|
|
if (this.isGrantedByOtherProviderName(permission.grantedProviders)) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const index = this.permissions.findIndex(per => per.name === permission.name); |
|
|
const index = updatedPermissions.findIndex(per => per.name === permission.name); |
|
|
|
|
|
if (index < 0) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
this.permissions = [ |
|
|
updatedPermissions = [ |
|
|
...this.permissions.slice(0, index), |
|
|
...updatedPermissions.slice(0, index), |
|
|
{ ...this.permissions[index], isGranted: checked }, |
|
|
{ ...updatedPermissions[index], isGranted: checked }, |
|
|
...this.permissions.slice(index + 1), |
|
|
...updatedPermissions.slice(index + 1), |
|
|
]; |
|
|
]; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
this.onChangeGroup(this.selectedGroup!); |
|
|
return updatedPermissions; |
|
|
this.setGrantCheckboxState(); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
onSelectAllChange(event: Event) { |
|
|
onSelectAllChange(event: Event) { |
|
|
const checked = (event.target as HTMLInputElement).checked; |
|
|
if (this.disabledSelectAllInAllTabs()) { |
|
|
this.selectAllTab = checked; |
|
|
return; |
|
|
|
|
|
|
|
|
if (this.filter()) { |
|
|
|
|
|
this.onFilterChange(''); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
this.permissions = this.permissions.map(permission => ({ |
|
|
const state = this.selectAllTabState(); |
|
|
...permission, |
|
|
const checked = !state.checked || state.indeterminate; |
|
|
isGranted: this.isGrantedByOtherProviderName(permission.grantedProviders) || checked, |
|
|
|
|
|
})); |
|
|
|
|
|
|
|
|
|
|
|
if (!this.disableSelectAllTab) { |
|
|
|
|
|
this.selectThisTab = checked; |
|
|
|
|
|
this.setTabCheckboxState(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (this.selectedGroup) { |
|
|
if (this.filter()) { |
|
|
this.onChangeGroup(this.selectedGroup); |
|
|
this.onFilterChange(''); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
this.setGrantCheckboxState(); |
|
|
this.permissionsState.update(permissions => |
|
|
|
|
|
permissions.map(permission => ({ |
|
|
|
|
|
...permission, |
|
|
|
|
|
isGranted: this.isGrantedByOtherProviderName(permission.grantedProviders) || checked, |
|
|
|
|
|
})), |
|
|
|
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
onFilterChange(value: string) { |
|
|
onFilterChange(value: string) { |
|
|
@ -506,7 +460,7 @@ export class PermissionManagementComponent { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!groups.some(group => group.name === this.selectedGroup?.name)) { |
|
|
if (!groups.some(group => group.name === this.selectedGroupState()?.name)) { |
|
|
this.onChangeGroup(groups[0]); |
|
|
this.onChangeGroup(groups[0]); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -519,19 +473,17 @@ export class PermissionManagementComponent { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
onChangeGroup(group: PermissionGroupDto) { |
|
|
onChangeGroup(group: PermissionGroupDto) { |
|
|
this.setDisabled(group.permissions); |
|
|
|
|
|
this.setSelectedGroup(group); |
|
|
this.setSelectedGroup(group); |
|
|
this.setTabCheckboxState(); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
submit() { |
|
|
submit() { |
|
|
if (this.modalBusy) { |
|
|
if (this.modalBusy()) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const unchangedPermissions = getPermissions(this.data.groups); |
|
|
const unchangedPermissions = getPermissions(this.data.groups); |
|
|
|
|
|
|
|
|
const changedPermissions: UpdatePermissionDto[] = this.permissions |
|
|
const changedPermissions: UpdatePermissionDto[] = this.permissionsState() |
|
|
.filter(per => |
|
|
.filter(per => |
|
|
(unchangedPermissions.find(unchanged => unchanged.name === per.name) || {}).isGranted === |
|
|
(unchangedPermissions.find(unchanged => unchanged.name === per.name) || {}).isGranted === |
|
|
per.isGranted |
|
|
per.isGranted |
|
|
@ -545,7 +497,7 @@ export class PermissionManagementComponent { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
this.modalBusy = true; |
|
|
this.modalBusy.set(true); |
|
|
this.service |
|
|
this.service |
|
|
.update(this.providerName, this.providerKey, { permissions: changedPermissions }) |
|
|
.update(this.providerName, this.providerKey, { permissions: changedPermissions }) |
|
|
.pipe( |
|
|
.pipe( |
|
|
@ -553,11 +505,7 @@ export class PermissionManagementComponent { |
|
|
switchMap(() => |
|
|
switchMap(() => |
|
|
this.shouldFetchAppConfig() ? this.configState.refreshAppState() : of(null), |
|
|
this.shouldFetchAppConfig() ? this.configState.refreshAppState() : of(null), |
|
|
), |
|
|
), |
|
|
finalize(() => { |
|
|
finalize(() => this.modalBusy.set(false)), |
|
|
if (this.modalBusy) { |
|
|
|
|
|
this.modalBusy = false; |
|
|
|
|
|
} |
|
|
|
|
|
}), |
|
|
|
|
|
) |
|
|
) |
|
|
.subscribe(() => { |
|
|
.subscribe(() => { |
|
|
this.toasterService.success('AbpUi::SavedSuccessfully'); |
|
|
this.toasterService.success('AbpUi::SavedSuccessfully'); |
|
|
@ -578,29 +526,16 @@ export class PermissionManagementComponent { |
|
|
|
|
|
|
|
|
this.data = permissionRes; |
|
|
this.data = permissionRes; |
|
|
this.permissionGroupSignal.set(groups); |
|
|
this.permissionGroupSignal.set(groups); |
|
|
this.permissions = getPermissions(groups); |
|
|
const permissions = getPermissions(groups); |
|
|
this.setSelectedGroup(groups[0]); |
|
|
this.permissionsState.set(permissions); |
|
|
|
|
|
this.disabledSelectAllInAllTabsState.set(isSelectAllDisabled(permissions, providerName)); |
|
|
this.disabledSelectAllInAllTabs = this.permissions.every( |
|
|
this.setSelectedGroup(groups[0] ?? null); |
|
|
per => |
|
|
|
|
|
per.isGranted && |
|
|
|
|
|
(per.grantedProviders ?? []).every(provider => provider.providerName !== providerName), |
|
|
|
|
|
); |
|
|
|
|
|
}), |
|
|
}), |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
initModal() { |
|
|
|
|
|
// TODO: Refactor
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
this.setDisabled(this.selectedGroup?.permissions || []); |
|
|
|
|
|
this.setTabCheckboxState(); |
|
|
|
|
|
this.setGrantCheckboxState(); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
getAssignedCount(groupName: string) { |
|
|
getAssignedCount(groupName: string) { |
|
|
return this.permissions.reduce( |
|
|
return this.permissionsState().reduce( |
|
|
(acc, val) => (val.groupName === groupName && val.isGranted ? acc + 1 : acc), |
|
|
(acc, val) => (val.groupName === groupName && val.isGranted ? acc + 1 : acc), |
|
|
0, |
|
|
0, |
|
|
); |
|
|
); |
|
|
@ -619,6 +554,41 @@ export class PermissionManagementComponent { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function isSelectAllDisabled( |
|
|
|
|
|
permissions: PermissionGrantInfoDto[] | undefined, |
|
|
|
|
|
providerName: string, |
|
|
|
|
|
): boolean { |
|
|
|
|
|
if (!permissions?.length) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return permissions.every( |
|
|
|
|
|
permission => |
|
|
|
|
|
permission.isGranted && |
|
|
|
|
|
permission.grantedProviders?.every(p => p.providerName !== providerName), |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function getSelectAllCheckboxState( |
|
|
|
|
|
permissions: PermissionGrantInfoDto[], |
|
|
|
|
|
providerName: string, |
|
|
|
|
|
): SelectAllCheckboxState { |
|
|
|
|
|
const selectablePermissions = permissions.filter(permission => |
|
|
|
|
|
(permission.grantedProviders ?? []).every(p => p.providerName === providerName), |
|
|
|
|
|
); |
|
|
|
|
|
const selectedPermissions = selectablePermissions.filter(permission => permission.isGranted); |
|
|
|
|
|
|
|
|
|
|
|
if (!selectablePermissions.length || selectedPermissions.length === 0) { |
|
|
|
|
|
return { checked: false, indeterminate: false }; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (selectedPermissions.length === selectablePermissions.length) { |
|
|
|
|
|
return { checked: true, indeterminate: false }; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return { checked: false, indeterminate: true }; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
function findParentPermissions( |
|
|
function findParentPermissions( |
|
|
permissions: PermissionGrantInfoDto[], |
|
|
permissions: PermissionGrantInfoDto[], |
|
|
permission: PermissionGrantInfoDto, |
|
|
permission: PermissionGrantInfoDto, |
|
|
|