diff --git a/devtools/projects/ng-devtools-backend/src/lib/client-event-subscribers.ts b/devtools/projects/ng-devtools-backend/src/lib/client-event-subscribers.ts index b89bde1aa960..32d0df8df252 100644 --- a/devtools/projects/ng-devtools-backend/src/lib/client-event-subscribers.ts +++ b/devtools/projects/ng-devtools-backend/src/lib/client-event-subscribers.ts @@ -51,7 +51,7 @@ import {ComponentTreeNode} from './interfaces'; import {ngDebugDependencyInjectionApiIsSupported} from './ng-debug-api/ng-debug-api'; import {setConsoleReference} from './set-console-reference'; import {serializeDirectiveState} from './state-serializer/state-serializer'; -import {runOutsideAngular} from './utils'; +import {runOutsideAngular, unwrapSignal} from './utils'; import {DirectiveForestHooks} from './hooks/hooks'; export const subscribeToClientEvents = ( @@ -194,7 +194,7 @@ const getNestedPropertiesCallback = } let data = current.instance; for (const prop of propPath) { - data = data[prop]; + data = unwrapSignal(data[prop]); if (!data) { console.error('Cannot access the properties', propPath, 'of', node); } diff --git a/devtools/projects/ng-devtools-backend/src/lib/state-serializer/serialized-descriptor-factory.ts b/devtools/projects/ng-devtools-backend/src/lib/state-serializer/serialized-descriptor-factory.ts index 67311d761a22..e25266d781ab 100644 --- a/devtools/projects/ng-devtools-backend/src/lib/state-serializer/serialized-descriptor-factory.ts +++ b/devtools/projects/ng-devtools-backend/src/lib/state-serializer/serialized-descriptor-factory.ts @@ -325,11 +325,11 @@ function getLevelDescriptorValue( const isReadonly = isSignal(prop); switch (type) { case PropType.Array: - return prop.map((_: any, idx: number) => + return value.map((_: any, idx: number) => continuation(value, idx, isReadonly, currentLevel + 1, level), ); case PropType.Object: - return getKeys(prop).reduce( + return getKeys(value).reduce( (accumulator, propName) => { if (!ignoreList.has(propName)) { accumulator[propName] = continuation( diff --git a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.html b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.html index 9c390af10847..dee01c775974 100644 --- a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.html +++ b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.html @@ -21,53 +21,57 @@ (mouseleave)="removeHighlight()" [style.padding-left]="15 + 15 * node.level + 'px'" > -
- @if (node.expandable) { - - } - {{ node.name }} - - @if (node.directives) { - [{{ node.directives }}] - } - @if (isSelected(node)) { - == $ng0 - } - - @switch(node.hydration?.status) { - @case('hydrated') { - water_drop +
+ @if (node.expandable) { + + } - @case('skipped') { - invert_colors_off + {{ node.name }} + + @if (node.directives) { + [{{ node.directives }}] } - @case('mismatched') { - error_outline + @if (isSelected(node)) { + == $ng0 } - } -
- @if(node.hydration?.status === 'mismatched' && (node.hydration.expectedNodeDetails || node.hydration.actualNodeDetails)) { -
- @if(node.hydration.expectedNodeDetails) { -
Expected Dom:
-
{{node.hydration.expectedNodeDetails}}
- } - @if(node.hydration.actualNodeDetails) { -
Actual Dom:
-
{{node.hydration.actualNodeDetails}}
+ + @switch (node.hydration?.status) { + @case ('hydrated') { + water_drop + } + @case ('skipped') { + invert_colors_off + } + @case ('mismatched') { + error_outline + } }
- } + @if ( + treeControl.isExpanded(node) && + node.hydration?.status === 'mismatched' && + (node.hydration.expectedNodeDetails || node.hydration.actualNodeDetails) + ) { +
+ @if (node.hydration.expectedNodeDetails) { +
Expected Dom:
+
{{node.hydration.expectedNodeDetails}}
+ } + @if (node.hydration.actualNodeDetails) { +
Actual Dom:
+
{{node.hydration.actualNodeDetails}}
+ } +
+ }
- - diff --git a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.ts b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.ts index 43ecc5b8b2f6..81cd5a6c6976 100644 --- a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.ts +++ b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.ts @@ -16,6 +16,7 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + ElementRef, EventEmitter, HostListener, Input, @@ -99,11 +100,13 @@ export class DirectiveForestComponent { readonly itemHeight = 18; private _initialized = false; + private resizeObserver: ResizeObserver; constructor( private _tabUpdate: TabUpdate, private _messageBus: MessageBus, private _cdr: ChangeDetectorRef, + private elementRef: ElementRef, ) { this.subscribeToInspectorEvents(); this._tabUpdate.tabUpdate$.pipe(takeUntilDestroyed()).subscribe(() => { @@ -114,6 +117,17 @@ export class DirectiveForestComponent { }); } }); + + // In some cases there a height changes, we need to recalculate the viewport size. + this.resizeObserver = new ResizeObserver(() => { + this.viewport.scrollToIndex(0); + this.viewport.checkViewportSize(); + }); + this.resizeObserver.observe(this.elementRef.nativeElement); + } + + ngOnDestroy(): void { + this.resizeObserver.disconnect(); } subscribeToInspectorEvents(): void { @@ -330,6 +344,10 @@ export class DirectiveForestComponent { } } + stopPropagation(event: Event): void { + event.stopPropagation(); + } + private _findMatchedNodes(): number[] { const indexesOfMatchedNodes: number[] = []; for (let i = 0; i < this.dataSource.data.length; i++) {