mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(devtools): filtering providers by token within "injector tree" tab (#53313)
In some injectors, there are LOTS of providers, making it slightly inconvenient to search for a certain one. This commit introduces a search-by-token for providers of a specific injector. PR Close #53313
This commit is contained in:
+60
-7
@@ -6,9 +6,11 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {NgForOf, NgIf} from '@angular/common';
|
||||
import {Component, inject, Input} from '@angular/core';
|
||||
import {Component, computed, inject, Input, signal} from '@angular/core';
|
||||
import {MatFormFieldModule} from '@angular/material/form-field';
|
||||
import {MatIconModule} from '@angular/material/icon';
|
||||
import {MatInputModule} from '@angular/material/input';
|
||||
import {MatSelectModule} from '@angular/material/select';
|
||||
import {MatTableModule} from '@angular/material/table';
|
||||
import {MatTooltipModule} from '@angular/material/tooltip';
|
||||
import {Events, MessageBus, SerializedInjector, SerializedProviderRecord} from 'protocol';
|
||||
@@ -19,8 +21,32 @@ import {Events, MessageBus, SerializedInjector, SerializedProviderRecord} from '
|
||||
<h1>
|
||||
Providers for {{ injector?.name }}
|
||||
</h1>
|
||||
<div *ngIf="injector" class="injector-providers">
|
||||
<table *ngIf="providers.length > 0" mat-table [dataSource]="providers" class="mat-elevation-z4">
|
||||
@if (injector){
|
||||
<div class="injector-providers">
|
||||
<mat-form-field appearance="fill" class="form-field-spacer">
|
||||
<mat-label>Search by token</mat-label>
|
||||
<input type="text" matInput
|
||||
placeholder="Provider token"
|
||||
(input)="searchToken.set($event.target.value)"
|
||||
[value]="searchToken()"
|
||||
/>
|
||||
<mat-icon matSuffix (click)="searchToken.set('')">close</mat-icon>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="form-field-spacer">
|
||||
<mat-label>Search by type</mat-label>
|
||||
<mat-select
|
||||
[value]="searchType()"
|
||||
(selectionChange)="searchType.set($event.value)"
|
||||
>
|
||||
<mat-option>None</mat-option>
|
||||
@for (type of providerTypes; track type) {
|
||||
<mat-option [value]="type">{{providerTypeToLabel[type]}}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
@if(visibleProviders().length > 0){
|
||||
<table mat-table [dataSource]="visibleProviders()" class="mat-elevation-z4">
|
||||
<ng-container matColumnDef="token">
|
||||
<th mat-header-cell *matHeaderCellDef> <h3 class="column-title">Token</h3> </th>
|
||||
<td mat-cell *matCellDef="let provider"> {{provider.token}} </td>
|
||||
@@ -32,7 +58,7 @@ import {Events, MessageBus, SerializedInjector, SerializedProviderRecord} from '
|
||||
@if (provider.type === 'multi') {
|
||||
multi (x{{ provider.index.length }})
|
||||
} @else {
|
||||
{{typeToLabel[provider.type]}}
|
||||
{{providerTypeToLabel[provider.type]}}
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
@@ -50,7 +76,10 @@ import {Events, MessageBus, SerializedInjector, SerializedProviderRecord} from '
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
}
|
||||
|
||||
</div>
|
||||
}
|
||||
`,
|
||||
styles: [`
|
||||
.select {
|
||||
@@ -62,6 +91,10 @@ import {Events, MessageBus, SerializedInjector, SerializedProviderRecord} from '
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.form-field-spacer {
|
||||
margin: 0 4px 0 4px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -108,13 +141,31 @@ import {Events, MessageBus, SerializedInjector, SerializedProviderRecord} from '
|
||||
}
|
||||
`],
|
||||
standalone: true,
|
||||
imports: [NgIf, NgForOf, MatTableModule, MatIconModule, MatTooltipModule],
|
||||
imports: [
|
||||
MatTableModule, MatIconModule, MatTooltipModule, MatInputModule, MatSelectModule,
|
||||
MatFormFieldModule
|
||||
],
|
||||
})
|
||||
export class InjectorProvidersComponent {
|
||||
@Input() injector: SerializedInjector;
|
||||
@Input() providers: SerializedProviderRecord[] = [];
|
||||
|
||||
typeToLabel = {
|
||||
searchToken = signal('');
|
||||
searchType = signal('');
|
||||
visibleProviders = computed(() => {
|
||||
const searchToken = this.searchToken().toLowerCase();
|
||||
const searchType = this.searchType();
|
||||
|
||||
const predicates: ((provider: SerializedProviderRecord) => boolean)[] = [];
|
||||
searchToken &&
|
||||
predicates.push((provider) => provider.token.toLowerCase().includes(searchToken));
|
||||
searchType && predicates.push((provider) => provider.type === searchType);
|
||||
|
||||
return this.providers.filter(
|
||||
(provider) => predicates.every((predicate) => predicate(provider)));
|
||||
});
|
||||
|
||||
providerTypeToLabel = {
|
||||
type: 'Type',
|
||||
existing: 'useExisting',
|
||||
factory: 'useFactory',
|
||||
@@ -122,6 +173,8 @@ export class InjectorProvidersComponent {
|
||||
value: 'useValue',
|
||||
};
|
||||
|
||||
providerTypes = Object.keys(this.providerTypeToLabel);
|
||||
|
||||
messageBus = inject(MessageBus<Events>);
|
||||
|
||||
select(row: SerializedProviderRecord) {
|
||||
|
||||
Reference in New Issue
Block a user