Skip to content

Commit 6b0457e

Browse files
committed
refactor(ama-mfe-ng-utils): simplify ResizeDirective
- remove unnecessary inputs - remove the notion of `channelId` - simplify style binding
1 parent 9a333ef commit 6b0457e

File tree

4 files changed

+28
-124
lines changed

4 files changed

+28
-124
lines changed

packages/@ama-mfe/ng-utils/src/resize/resize.consumer.service.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ describe('ResizeConsumerService', () => {
5656
}
5757
};
5858
resizeHandlerService.supportedVersions['1.0'](resizeMessage);
59-
expect(resizeHandlerService.newHeightFromChannel()).toEqual({ height: 500, channelId: 'test' });
59+
expect(resizeHandlerService.heightPx()).toEqual(500);
6060
});
6161

6262
it('should have the correct message type', () => {

packages/@ama-mfe/ng-utils/src/resize/resize.consumer.service.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,14 @@ import {
2222
/**
2323
* This service listens for resize messages and updates the height of elements based on the received messages.
2424
*/
25-
@Injectable({
26-
providedIn: 'root'
27-
})
25+
@Injectable()
2826
export class ResizeConsumerService implements MessageConsumer<ResizeMessage> {
29-
private readonly newHeight = signal<{ height: number; channelId: string } | undefined>(undefined);
27+
private readonly heightPxSignal = signal<number | undefined>(undefined);
3028

3129
/**
3230
* A readonly signal that provides the new height information from the channel.
3331
*/
34-
public readonly newHeightFromChannel = this.newHeight.asReadonly();
32+
public readonly heightPx = this.heightPxSignal.asReadonly();
3533

3634
/**
3735
* The type of messages this service handles ('resize').
@@ -46,7 +44,7 @@ export class ResizeConsumerService implements MessageConsumer<ResizeMessage> {
4644
* Use the message paylod to compute a new height and emit it via the public signal
4745
* @param message message to consume
4846
*/
49-
'1.0': (message: RoutedMessage<ResizeV1_0>) => this.newHeight.set({ height: message.payload.height, channelId: message.from })
47+
'1.0': (message: RoutedMessage<ResizeV1_0>) => this.heightPxSignal.set(message.payload.height)
5048
};
5149

5250
private readonly consumerManagerService = inject(ConsumerManagerService);
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
Component,
33
DebugElement,
4-
Renderer2,
54
} from '@angular/core';
65
import {
76
ComponentFixture,
@@ -19,103 +18,50 @@ import {
1918

2019
@Component({
2120
imports: [ScalableDirective],
22-
standalone: true,
23-
template: `<div [connect]="connect" [scalable]="scalableValue"></div>`
21+
template: `<div scalable></div>`
2422
})
25-
class TestComponent {
26-
public connect = 'testConnectId';
27-
public scalableValue: string | undefined = 'testScalableId';
28-
}
23+
class TestComponent {}
2924

3025
describe('ScalableDirective', () => {
3126
let parentComponentFixture: ComponentFixture<TestComponent>;
3227
let directiveEl: DebugElement;
3328
let directiveInstance: ScalableDirective;
3429
let resizeHandlerService: ResizeConsumerService;
35-
let renderer: Renderer2;
3630

3731
beforeEach(() => {
38-
const resizeHandlerServiceMock = {
39-
start: jest.fn(),
40-
newHeightFromChannel: jest.fn().mockReturnValue({ channelId: 'testScalableId', height: 200 })
32+
const resizeConsumerMock = {
33+
heightPx: jest.fn().mockReturnValue(200)
4134
};
4235

4336
parentComponentFixture = TestBed.configureTestingModule({
44-
imports: [TestComponent, ScalableDirective],
45-
providers: [
46-
Renderer2,
47-
{ provide: ResizeConsumerService, useValue: resizeHandlerServiceMock }
48-
49-
]
50-
}).createComponent(TestComponent);
37+
imports: [TestComponent, ScalableDirective]
38+
})
39+
.overrideDirective(ScalableDirective, {
40+
set: {
41+
providers: [{ provide: ResizeConsumerService, useValue: resizeConsumerMock }]
42+
}
43+
})
44+
.createComponent(TestComponent);
5145

5246
parentComponentFixture.detectChanges();
5347
directiveEl = parentComponentFixture.debugElement.query(By.directive(ScalableDirective));
5448
directiveInstance = directiveEl.injector.get(ScalableDirective);
5549
resizeHandlerService = directiveEl.injector.get(ResizeConsumerService);
56-
renderer = directiveEl.injector.get(Renderer2);
5750
});
5851

5952
it('should create an instance', () => {
6053
expect(directiveInstance).toBeTruthy();
6154
});
6255

63-
it('should start the resize handler service on initialization', () => {
64-
expect(resizeHandlerService.start).toHaveBeenCalled();
65-
});
66-
67-
it('should set the height style on the element with the channelId from scalable input', () => {
68-
const channelId = 'scalable-channel-id';
69-
jest.spyOn(resizeHandlerService, 'newHeightFromChannel').mockReturnValue({ height: 300, channelId });
70-
const rendererSpy = jest.spyOn(renderer, 'setStyle');
71-
parentComponentFixture.componentInstance.scalableValue = channelId;
72-
parentComponentFixture.detectChanges();
73-
expect(rendererSpy).toHaveBeenCalledWith(directiveEl.nativeElement, 'height', '300px');
74-
rendererSpy.mockClear();
75-
});
76-
77-
it('should set the height style on the element with the channelId from connect input', () => {
78-
const channelId = 'connect-channel-id';
79-
jest.spyOn(resizeHandlerService, 'newHeightFromChannel').mockReturnValue({ height: 400, channelId });
80-
const rendererSpy = jest.spyOn(renderer, 'setStyle');
81-
parentComponentFixture.componentInstance.scalableValue = undefined;
82-
parentComponentFixture.componentInstance.connect = channelId;
83-
parentComponentFixture.detectChanges();
84-
expect(rendererSpy).toHaveBeenCalledWith(directiveEl.nativeElement, 'height', '400px');
85-
rendererSpy.mockClear();
86-
});
87-
88-
it('scalable input should take precedence over connect input', () => {
89-
const connectChannelId = 'connect-channel-id';
90-
const scalableChannelId = 'scalable-channel-id';
91-
jest.spyOn(resizeHandlerService, 'newHeightFromChannel').mockReturnValue({ height: 400, channelId: scalableChannelId });
92-
const rendererSpy = jest.spyOn(renderer, 'setStyle');
93-
parentComponentFixture.componentInstance.scalableValue = scalableChannelId;
94-
parentComponentFixture.componentInstance.connect = connectChannelId;
95-
parentComponentFixture.detectChanges();
96-
expect(rendererSpy).toHaveBeenCalledWith(directiveEl.nativeElement, 'height', '400px');
97-
rendererSpy.mockClear();
98-
});
99-
100-
it('should not update the style if channelId does not match', () => {
101-
const connectChannelId = 'connect-channel-id';
102-
const scalableChannelId = 'scalable-channel-id';
103-
jest.spyOn(resizeHandlerService, 'newHeightFromChannel').mockReturnValue({ height: 400, channelId: scalableChannelId });
104-
const rendererSpy = jest.spyOn(renderer, 'setStyle');
105-
parentComponentFixture.componentInstance.scalableValue = 'not-matching-channel-id';
106-
parentComponentFixture.componentInstance.connect = connectChannelId;
56+
it('should set the height style on the element', () => {
57+
jest.spyOn(resizeHandlerService, 'heightPx').mockReturnValue(300);
10758
parentComponentFixture.detectChanges();
108-
expect(rendererSpy).not.toHaveBeenCalled();
109-
rendererSpy.mockClear();
59+
expect(directiveEl.nativeElement.getAttribute('style')).toBe('height: 300px;');
11060
});
11161

112-
it('should not set the height style on the element when newHeightFromChannel is not available', () => {
113-
const channelId = 'scalable-channel-id';
114-
jest.spyOn(resizeHandlerService, 'newHeightFromChannel').mockReturnValue(undefined);
115-
const rendererSpy = jest.spyOn(renderer, 'setStyle');
116-
parentComponentFixture.componentInstance.scalableValue = channelId;
62+
it('should not set the height style on the element when heightPx is not available', () => {
63+
jest.spyOn(resizeHandlerService, 'heightPx').mockReturnValue(undefined);
11764
parentComponentFixture.detectChanges();
118-
expect(rendererSpy).not.toHaveBeenCalled();
119-
rendererSpy.mockClear();
65+
expect(directiveEl.nativeElement.getAttribute('style')).toBe('');
12066
});
12167
});
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import {
2-
computed,
32
Directive,
4-
effect,
5-
ElementRef,
63
inject,
7-
input,
8-
Renderer2,
94
} from '@angular/core';
105
import {
116
ResizeConsumerService,
@@ -16,46 +11,11 @@ import {
1611
*/
1712
@Directive({
1813
selector: '[scalable]',
19-
standalone: true
14+
host: {
15+
'[style.height.px]': 'resizeConsumer.heightPx()'
16+
},
17+
providers: [ResizeConsumerService]
2018
})
2119
export class ScalableDirective {
22-
/**
23-
* The connection ID for the element, used as channel id backup
24-
*/
25-
public connect = input<string>();
26-
27-
/**
28-
* The channel id
29-
*/
30-
public scalable = input<string>();
31-
32-
private readonly resizeHandler = inject(ResizeConsumerService);
33-
34-
/**
35-
* This signal checks if the current channel requesting the resize matches the channel ID from the resize handler.
36-
* If they match, it returns the new height information; otherwise, it returns undefined.
37-
*/
38-
private readonly newHeightFromChannel = computed(() => {
39-
const channelAskingResize = this.scalable() || this.connect();
40-
const newHeightFromChannel = this.resizeHandler.newHeightFromChannel();
41-
if (channelAskingResize && newHeightFromChannel?.channelId === channelAskingResize) {
42-
return newHeightFromChannel;
43-
}
44-
return undefined;
45-
});
46-
47-
constructor() {
48-
const elem = inject(ElementRef);
49-
const renderer = inject(Renderer2);
50-
51-
this.resizeHandler.start();
52-
53-
/** When a new height value is received set the height of the host element (in pixels) */
54-
effect(() => {
55-
const newHeightFromChannel = this.newHeightFromChannel();
56-
if (newHeightFromChannel) {
57-
renderer.setStyle(elem.nativeElement, 'height', `${newHeightFromChannel.height}px`);
58-
}
59-
});
60-
}
20+
protected readonly resizeConsumer = inject(ResizeConsumerService);
6121
}

0 commit comments

Comments
 (0)