Browse Source

Merge branch 'issue-24299' into test-branch-24299

test-branch-24299
Fahri Gedik 1 month ago
parent
commit
5fd8818831
  1. 77
      npm/ng-packs/packages/components/lookup/src/lib/lookup-search.component.html
  2. 5
      npm/ng-packs/packages/components/lookup/src/lib/lookup-search.component.scss
  3. 23
      npm/ng-packs/packages/components/lookup/src/lib/lookup-search.component.ts
  4. 10
      npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/permission-checkbox-list/permission-checkbox-list.component.html
  5. 4
      npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/permission-checkbox-list/permission-checkbox-list.component.scss
  6. 1
      npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/permission-checkbox-list/permission-checkbox-list.component.ts
  7. 17
      npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/provider-key-search/provider-key-search.component.ts
  8. 51
      npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/resource-permission-list/resource-permission-list.component.html
  9. 29
      npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/resource-permission-management.component.ts
  10. 2
      npm/ng-packs/packages/permission-management/src/lib/enums/index.ts
  11. 136
      npm/ng-packs/tsconfig.base.json

77
npm/ng-packs/packages/components/lookup/src/lib/lookup-search.component.html

@ -1,46 +1,45 @@
<div class="abp-lookup-container position-relative">
@if (label()) {
<label class="form-label">{{ label() | abpLocalization }}</label>
@if (label()) {
<label class="form-label">{{ label() | abpLocalization }}</label>
}
<div class="input-group">
<input type="text" class="form-control" [placeholder]="placeholder() | abpLocalization" [ngModel]="displayValue()"
(ngModelChange)="onSearchInput($event)" (focus)="onSearchFocus()" (blur)="onSearchBlur($event)"
[disabled]="disabled()" />
@if (displayValue() && !disabled()) {
<button type="button" class="btn btn-outline-secondary" (mousedown)="clearSelection()" tabindex="-1">
<i class="fa fa-times"></i>
</button>
}
</div>
<div class="input-group">
<input type="text" class="form-control" [placeholder]="placeholder() | abpLocalization"
[ngModel]="displayValue()" (ngModelChange)="onSearchInput($event)" (focus)="onSearchFocus()"
(blur)="onSearchBlur($event)" [disabled]="disabled()" />
@if (displayValue() && !disabled()) {
<button type="button" class="btn btn-outline-secondary" (mousedown)="clearSelection()" tabindex="-1">
<i class="fa fa-times"></i>
</button>
}
@if (showDropdown() && !disabled()) {
<div class="abp-lookup-dropdown list-group position-absolute w-100 shadow">
@if (isLoading()) {
<div class="list-group-item text-center py-3">
<i class="fa fa-spinner fa-spin me-2"></i>
{{ 'AbpUi::Loading' | abpLocalization }}
</div>
@if (showDropdown() && !disabled()) {
<div class="abp-lookup-dropdown list-group position-absolute w-100 shadow"
style="z-index: 1050; max-height: 200px; overflow-y: auto;">
@if (isLoading()) {
<div class="list-group-item text-center py-3">
<i class="fa fa-spinner fa-spin me-2"></i>
{{ 'AbpUi::Loading' | abpLocalization }}
</div>
} @else if (searchResults().length > 0) {
@for (item of searchResults(); track item.key) {
<button type="button" class="list-group-item list-group-item-action" (mousedown)="selectItem(item)">
@if (itemTemplate()) {
<ng-container *ngTemplateOutlet="itemTemplate()!; context: { $implicit: item }"></ng-container>
} @else {
{{ getDisplayValue(item) }}
}
</button>
}
} @else if (displayValue()) {
@if (noResultsTemplate()) {
<ng-container *ngTemplateOutlet="noResultsTemplate()!"></ng-container>
} @else {
<div class="list-group-item text-muted">
{{ 'AbpUi::NoRecordsFound' | abpLocalization }}
</div>
}
}
} @else if (searchResults().length > 0) {
@for (item of searchResults(); track item.key) {
<button type="button" class="list-group-item list-group-item-action" (mousedown)="selectItem(item)">
@if (itemTemplate()) {
<ng-container *ngTemplateOutlet="itemTemplate()!; context: { $implicit: item }" />
} @else {
{{ getDisplayValue(item) }}
}
</button>
}
} @else if (displayValue()) {
@if (noResultsTemplate()) {
<ng-container *ngTemplateOutlet="noResultsTemplate()!" />
} @else {
<div class="list-group-item text-muted">
{{ 'AbpUi::NoRecordsFound' | abpLocalization }}
</div>
}
}
</div>
}
</div>

5
npm/ng-packs/packages/components/lookup/src/lib/lookup-search.component.scss

@ -0,0 +1,5 @@
.abp-lookup-dropdown {
z-index: 1050;
max-height: 200px;
overflow-y: auto;
}

23
npm/ng-packs/packages/components/lookup/src/lib/lookup-search.component.ts

@ -5,15 +5,17 @@ import {
model,
signal,
OnInit,
OnDestroy,
ChangeDetectionStrategy,
TemplateRef,
contentChild,
DestroyRef,
inject,
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { LocalizationPipe } from '@abp/ng.core';
import { Subject, Observable, debounceTime, distinctUntilChanged, takeUntil, of } from 'rxjs';
import { Subject, Observable, debounceTime, distinctUntilChanged, of, finalize } from 'rxjs';
export interface LookupItem {
key: string;
@ -26,10 +28,12 @@ export type LookupSearchFn<T = LookupItem> = (filter: string) => Observable<T[]>
@Component({
selector: 'abp-lookup-search',
templateUrl: './lookup-search.component.html',
styleUrl: './lookup-search.component.scss',
imports: [CommonModule, FormsModule, LocalizationPipe],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LookupSearchComponent<T extends LookupItem = LookupItem> implements OnInit, OnDestroy {
export class LookupSearchComponent<T extends LookupItem = LookupItem> implements OnInit {
private readonly destroyRef = inject(DestroyRef);
readonly label = input<string>();
readonly placeholder = input<string>('');
@ -55,23 +59,17 @@ export class LookupSearchComponent<T extends LookupItem = LookupItem> implements
readonly isLoading = signal(false);
private readonly searchSubject = new Subject<string>();
private readonly destroy$ = new Subject<void>();
ngOnInit() {
this.searchSubject.pipe(
debounceTime(this.debounceTime()),
distinctUntilChanged(),
takeUntil(this.destroy$)
takeUntilDestroyed(this.destroyRef)
).subscribe(filter => {
this.performSearch(filter);
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
onSearchInput(filter: string) {
this.displayValue.set(filter);
this.showDropdown.set(true);
@ -120,15 +118,14 @@ export class LookupSearchComponent<T extends LookupItem = LookupItem> implements
this.isLoading.set(true);
this.searchFn()(filter).pipe(
takeUntil(this.destroy$)
takeUntilDestroyed(this.destroyRef),
finalize(() => this.isLoading.set(false))
).subscribe({
next: results => {
this.searchResults.set(results);
this.isLoading.set(false);
},
error: () => {
this.searchResults.set([]);
this.isLoading.set(false);
}
});
}

10
npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/permission-checkbox-list/permission-checkbox-list.component.html

@ -3,20 +3,20 @@
<h5>{{ title() | abpLocalization }}</h5>
}
<div class="form-check form-switch mb-2">
<input class="form-check-input" type="checkbox" [id]="'grantAll-' + idPrefix()"
<input class="form-check-input" type="checkbox" id="grantAll-{{ idPrefix() }}"
[checked]="state.allPermissionsSelected()"
(change)="state.toggleAllPermissions(!state.allPermissionsSelected())" />
<label class="form-check-label" [for]="'grantAll-' + idPrefix()">
<label class="form-check-label" for="grantAll-{{ idPrefix() }}">
{{ 'AbpPermissionManagement::GrantAllResourcePermissions' | abpLocalization }}
</label>
</div>
<div class="border rounded p-3" style="max-height: 300px; overflow-y: auto;">
<div class="abp-permission-list-container border rounded p-3">
@for (perm of permissions(); track perm.name) {
<div class="form-check">
<input class="form-check-input" type="checkbox" [id]="'perm-' + idPrefix() + '-' + perm.name"
<input class="form-check-input" type="checkbox" id="perm-{{ idPrefix() }}-{{ perm.name }}"
[checked]="state.isPermissionSelected(perm.name || '')"
(change)="state.togglePermission(perm.name || '')" />
<label class="form-check-label" [for]="'perm-' + idPrefix() + '-' + perm.name">
<label class="form-check-label" for="perm-{{ idPrefix() }}-{{ perm.name }}">
{{ perm.displayName }}
</label>
</div>

4
npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/permission-checkbox-list/permission-checkbox-list.component.scss

@ -0,0 +1,4 @@
.abp-permission-list-container {
max-height: 300px;
overflow-y: auto;
}

1
npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/permission-checkbox-list/permission-checkbox-list.component.ts

@ -10,6 +10,7 @@ interface PermissionItem {
@Component({
selector: 'abp-permission-checkbox-list',
templateUrl: './permission-checkbox-list.component.html',
styleUrl: './permission-checkbox-list.component.scss',
imports: [LocalizationPipe],
changeDetection: ChangeDetectionStrategy.OnPush,
})

17
npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/provider-key-search/provider-key-search.component.ts

@ -1,7 +1,8 @@
import { Component, input, inject, OnInit, OnDestroy, ChangeDetectionStrategy } from '@angular/core';
import { Component, input, inject, OnInit, ChangeDetectionStrategy, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { PermissionsService } from '@abp/ng.permission-management/proxy';
import { LookupSearchComponent, LookupItem } from '@abp/ng.components/lookup';
import { Observable, map, Subject, takeUntil } from 'rxjs';
import { Observable, map } from 'rxjs';
import { ResourcePermissionStateService } from '../../../services/resource-permission-state.service';
interface ProviderKeyLookupItem extends LookupItem {
@ -15,25 +16,19 @@ interface ProviderKeyLookupItem extends LookupItem {
imports: [LookupSearchComponent],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ProviderKeySearchComponent implements OnInit, OnDestroy {
export class ProviderKeySearchComponent implements OnInit {
readonly state = inject(ResourcePermissionStateService);
private readonly service = inject(PermissionsService);
private readonly destroyRef = inject(DestroyRef);
readonly resourceName = input.required<string>();
private readonly destroy$ = new Subject<void>();
searchFn: (filter: string) => Observable<ProviderKeyLookupItem[]> = () => new Observable();
ngOnInit() {
this.searchFn = (filter: string) => this.loadProviderKeys(filter);
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
onItemSelected(item: ProviderKeyLookupItem) {
// State is already updated via displayValue and selectedValue bindings
// This handler can be used for additional side effects if needed
@ -60,7 +55,7 @@ export class ProviderKeySearchComponent implements OnInit, OnDestroy {
providerKey: k.providerKey || '',
providerDisplayName: k.providerDisplayName || undefined,
}))),
takeUntil(this.destroy$)
takeUntilDestroyed(this.destroyRef)
);
}
}

51
npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/resource-permission-list/resource-permission-list.component.html

@ -1,28 +1,41 @@
<div class="d-grid gap-2 mb-3 d-md-flex justify-content-md-end">
<button class="btn btn-sm btn-primary" type="button" (click)="addClicked.emit()">
<i class="fa fa-plus me-1"></i>
{{ 'AbpPermissionManagement::AddResourcePermission' | abpLocalization }}
</button>
<button class="btn btn-sm btn-primary" type="button" (click)="addClicked.emit()">
<i class="fa fa-plus me-1"></i>
{{ 'AbpPermissionManagement::AddResourcePermission' | abpLocalization }}
</button>
</div>
<ng-template #actionsTemplate let-row>
<div class="btn-group btn-group-sm" role="group">
<button class="btn btn-outline-primary" type="button" (click)="editClicked.emit(row)"
[title]="'AbpUi::Edit' | abpLocalization">
<i class="fa fa-edit"></i>
</button>
<button class="btn btn-outline-danger" type="button" (click)="deleteClicked.emit(row)"
[title]="'AbpUi::Delete' | abpLocalization">
<i class="fa fa-trash"></i>
</button>
</div>
<div class="btn-group btn-group-sm" role="group">
<button
class="btn btn-outline-primary"
type="button"
(click)="editClicked.emit(row)"
[title]="'AbpUi::Edit' | abpLocalization"
>
<i class="fa fa-edit"></i>
</button>
<button
class="btn btn-outline-danger"
type="button"
(click)="deleteClicked.emit(row)"
[title]="'AbpUi::Delete' | abpLocalization"
>
<i class="fa fa-trash"></i>
</button>
</div>
</ng-template>
@if (state.resourcePermissions().length > 0) {
<abp-extensible-table [data]="state.resourcePermissions()" [recordsTotal]="state.totalCount()" [list]="list"
[actionsTemplate]="actionsTemplate" actionsText="AbpUi::Actions"></abp-extensible-table>
<abp-extensible-table
[data]="state.resourcePermissions()"
[recordsTotal]="state.totalCount()"
[list]="list"
[actionsTemplate]="actionsTemplate"
actionsText="AbpUi::Actions"
/>
} @else {
<div class="alert alert-info">
<div class="alert alert-info">
{{ 'AbpPermissionManagement::NoPermissionsAssigned' | abpLocalization }}
</div>
}
</div>
}

29
npm/ng-packs/packages/permission-management/src/lib/components/resource-permission-management/resource-permission-management.component.ts

@ -18,6 +18,8 @@ import {
model,
OnInit,
effect,
untracked,
signal,
} from '@angular/core';
import { finalize, switchMap, of } from 'rxjs';
import { ResourcePermissionStateService } from '../../services/resource-permission-state.service';
@ -26,6 +28,8 @@ import { ResourcePermissionFormComponent } from './resource-permission-form/reso
import { eResourcePermissionViewModes } from '../../enums/view-modes';
const DEFAULT_MAX_RESULT_COUNT = 10;
@Component({
selector: 'abp-resource-permission-management',
templateUrl: './resource-permission-management.component.html',
@ -55,33 +59,40 @@ export class ResourcePermissionManagementComponent implements OnInit {
readonly visible = model<boolean>(false);
private previousVisible = false;
private readonly previousVisible = signal(false);
constructor() {
effect(() => {
this.state.resourceName.set(this.resourceName());
this.state.resourceKey.set(this.resourceKey());
this.state.resourceDisplayName.set(this.resourceDisplayName());
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();
if (isVisible && !this.previousVisible) {
const wasVisible = this.previousVisible();
if (isVisible && !wasVisible) {
this.openModal();
} else if (!isVisible && this.previousVisible) {
} else if (!isVisible && wasVisible) {
this.state.reset();
}
this.previousVisible = isVisible;
untracked(() => this.previousVisible.set(isVisible));
});
}
ngOnInit() {
this.list.maxResultCount = 10;
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 || 10;
const maxResultCount = query.maxResultCount || DEFAULT_MAX_RESULT_COUNT;
const paginatedData = allData.slice(skipCount, skipCount + maxResultCount);

2
npm/ng-packs/packages/permission-management/src/lib/enums/index.ts

@ -0,0 +1,2 @@
export * from './view-modes';
export * from './components';

136
npm/ng-packs/tsconfig.base.json

@ -10,114 +10,46 @@
"importHelpers": true,
"target": "es2020",
"module": "esnext",
"lib": [
"es2020",
"dom"
],
"lib": ["es2020", "dom"],
"esModuleInterop": true,
"baseUrl": "./",
"allowSyntheticDefaultImports": true,
"paths": {
"@abp/ng.account": [
"packages/account/src/public-api.ts"
],
"@abp/ng.account.core": [
"packages/account-core/src/public-api.ts"
],
"@abp/ng.account.core/proxy": [
"packages/account-core/proxy/src/public-api.ts"
],
"@abp/ng.account/config": [
"packages/account/config/src/public-api.ts"
],
"@abp/ng.components": [
"packages/components/src/public-api.ts"
],
"@abp/ng.components/chart.js": [
"packages/components/chart.js/src/public-api.ts"
],
"@abp/ng.components/extensible": [
"packages/components/extensible/src/public-api.ts"
],
"@abp/ng.components/lookup": [
"packages/components/lookup/src/public-api.ts"
],
"@abp/ng.components/page": [
"packages/components/page/src/public-api.ts"
],
"@abp/ng.components/tree": [
"packages/components/tree/src/public-api.ts"
],
"@abp/ng.core": [
"packages/core/src/public-api.ts"
],
"@abp/ng.core/locale": [
"packages/core/locale/src/public-api.ts"
],
"@abp/ng.core/testing": [
"packages/core/testing/src/public-api.ts"
],
"@abp/ng.feature-management": [
"packages/feature-management/src/public-api.ts"
],
"@abp/ng.feature-management/proxy": [
"packages/feature-management/proxy/src/public-api.ts"
],
"@abp/ng.identity": [
"packages/identity/src/public-api.ts"
],
"@abp/ng.identity/config": [
"packages/identity/config/src/public-api.ts"
],
"@abp/ng.identity/proxy": [
"packages/identity/proxy/src/public-api.ts"
],
"@abp/ng.oauth": [
"packages/oauth/src/public-api.ts"
],
"@abp/ng.permission-management": [
"packages/permission-management/src/public-api.ts"
],
"@abp/ng.account": ["packages/account/src/public-api.ts"],
"@abp/ng.account.core": ["packages/account-core/src/public-api.ts"],
"@abp/ng.account.core/proxy": ["packages/account-core/proxy/src/public-api.ts"],
"@abp/ng.account/config": ["packages/account/config/src/public-api.ts"],
"@abp/ng.components": ["packages/components/src/public-api.ts"],
"@abp/ng.components/chart.js": ["packages/components/chart.js/src/public-api.ts"],
"@abp/ng.components/extensible": ["packages/components/extensible/src/public-api.ts"],
"@abp/ng.components/lookup": ["packages/components/lookup/src/public-api.ts"],
"@abp/ng.components/page": ["packages/components/page/src/public-api.ts"],
"@abp/ng.components/tree": ["packages/components/tree/src/public-api.ts"],
"@abp/ng.core": ["packages/core/src/public-api.ts"],
"@abp/ng.core/locale": ["packages/core/locale/src/public-api.ts"],
"@abp/ng.core/testing": ["packages/core/testing/src/public-api.ts"],
"@abp/ng.feature-management": ["packages/feature-management/src/public-api.ts"],
"@abp/ng.feature-management/proxy": ["packages/feature-management/proxy/src/public-api.ts"],
"@abp/ng.identity": ["packages/identity/src/public-api.ts"],
"@abp/ng.identity/config": ["packages/identity/config/src/public-api.ts"],
"@abp/ng.identity/proxy": ["packages/identity/proxy/src/public-api.ts"],
"@abp/ng.oauth": ["packages/oauth/src/public-api.ts"],
"@abp/ng.permission-management": ["packages/permission-management/src/public-api.ts"],
"@abp/ng.permission-management/proxy": [
"packages/permission-management/proxy/src/public-api.ts"
],
"@abp/ng.setting-management": [
"packages/setting-management/src/public-api.ts"
],
"@abp/ng.setting-management/config": [
"packages/setting-management/config/src/public-api.ts"
],
"@abp/ng.setting-management/proxy": [
"packages/setting-management/proxy/src/public-api.ts"
],
"@abp/ng.tenant-management": [
"packages/tenant-management/src/public-api.ts"
],
"@abp/ng.tenant-management/config": [
"packages/tenant-management/config/src/public-api.ts"
],
"@abp/ng.tenant-management/proxy": [
"packages/tenant-management/proxy/src/public-api.ts"
],
"@abp/ng.theme.basic": [
"packages/theme-basic/src/public-api.ts"
],
"@abp/ng.theme.basic/testing": [
"packages/theme-basic/testing/src/public-api.ts"
],
"@abp/ng.theme.shared": [
"packages/theme-shared/src/public-api.ts"
],
"@abp/ng.theme.shared/testing": [
"packages/theme-shared/testing/src/public-api.ts"
],
"@abp/nx.generators": [
"packages/generators/src/index.ts"
]
"@abp/ng.setting-management": ["packages/setting-management/src/public-api.ts"],
"@abp/ng.setting-management/config": ["packages/setting-management/config/src/public-api.ts"],
"@abp/ng.setting-management/proxy": ["packages/setting-management/proxy/src/public-api.ts"],
"@abp/ng.tenant-management": ["packages/tenant-management/src/public-api.ts"],
"@abp/ng.tenant-management/config": ["packages/tenant-management/config/src/public-api.ts"],
"@abp/ng.tenant-management/proxy": ["packages/tenant-management/proxy/src/public-api.ts"],
"@abp/ng.theme.basic": ["packages/theme-basic/src/public-api.ts"],
"@abp/ng.theme.basic/testing": ["packages/theme-basic/testing/src/public-api.ts"],
"@abp/ng.theme.shared": ["packages/theme-shared/src/public-api.ts"],
"@abp/ng.theme.shared/testing": ["packages/theme-shared/testing/src/public-api.ts"],
"@abp/nx.generators": ["packages/generators/src/index.ts"]
}
},
"exclude": [
"node_modules",
"tmp"
]
}
"exclude": ["node_modules", "tmp"]
}

Loading…
Cancel
Save