-
Notifications
You must be signed in to change notification settings - Fork 311
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NAS-132779 / 25.04 / Fibre channel port card (#11141)
* NAS-132779: Fibre channel port card * NAS-132779: PR update * NAS-132779: PR update * NAS-132779: PR Update
- Loading branch information
1 parent
8d8fa56
commit 8570a11
Showing
95 changed files
with
488 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
...all-targets/target-details/fibre-channel-port-card/fibre-channel-port-card.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<mat-card class="card"> | ||
<mat-card-header> | ||
<h3 mat-card-title> | ||
{{ 'Fibre Channel Port' | translate }} | ||
</h3> | ||
</mat-card-header> | ||
<mat-card-content> | ||
<p>{{ 'Name' | translate }}: {{ port().id }}</p> | ||
<p>{{ 'Controller A WWPN' | translate }}: {{ port().wwpn }}</p> | ||
<p>{{ 'Controller B WWPN' | translate }}: {{ port().wwpn_b }}</p> | ||
</mat-card-content> | ||
</mat-card> |
37 changes: 37 additions & 0 deletions
37
...-targets/target-details/fibre-channel-port-card/fibre-channel-port-card.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { createComponentFactory, Spectator } from '@ngneat/spectator/jest'; | ||
import { TranslateModule } from '@ngx-translate/core'; | ||
import { FibreChannelPort } from 'app/interfaces/fibre-channel.interface'; | ||
import { FibreChannelPortCardComponent } from './fibre-channel-port-card.component'; | ||
|
||
describe('FibreChannelPortCardComponent', () => { | ||
let spectator: Spectator<FibreChannelPortCardComponent>; | ||
const createComponent = createComponentFactory({ | ||
component: FibreChannelPortCardComponent, | ||
imports: [TranslateModule.forRoot()], | ||
}); | ||
|
||
beforeEach(() => { | ||
spectator = createComponent({ | ||
props: { | ||
port: { | ||
id: 'Port-1', | ||
wwpn: '10:00:00:00:c9:20:00:00', | ||
wwpn_b: '10:00:00:00:c9:20:00:01', | ||
} as unknown as FibreChannelPort, | ||
}, | ||
}); | ||
}); | ||
|
||
it('renders Fibre Channel Port title', () => { | ||
const title = spectator.query('h3[mat-card-title]'); | ||
expect(title).toHaveText('Fibre Channel Port'); | ||
}); | ||
|
||
it('displays port details correctly', () => { | ||
const content = spectator.queryAll('mat-card-content p'); | ||
expect(content).toHaveLength(3); | ||
expect(content[0]).toHaveText('Name: Port-1'); | ||
expect(content[1]).toHaveText('Controller A WWPN: 10:00:00:00:c9:20:00:00'); | ||
expect(content[2]).toHaveText('Controller B WWPN: 10:00:00:00:c9:20:00:01'); | ||
}); | ||
}); |
24 changes: 24 additions & 0 deletions
24
...t/all-targets/target-details/fibre-channel-port-card/fibre-channel-port-card.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { ChangeDetectionStrategy, Component, input } from '@angular/core'; | ||
import { | ||
MatCard, MatCardContent, MatCardHeader, MatCardTitle, | ||
} from '@angular/material/card'; | ||
import { TranslateModule } from '@ngx-translate/core'; | ||
import { FibreChannelPort } from 'app/interfaces/fibre-channel.interface'; | ||
|
||
@Component({ | ||
selector: 'ix-fibre-channel-port-card', | ||
styleUrls: ['./fibre-channel-port-card.component.scss'], | ||
templateUrl: './fibre-channel-port-card.component.html', | ||
standalone: true, | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
imports: [ | ||
MatCard, | ||
MatCardHeader, | ||
MatCardTitle, | ||
TranslateModule, | ||
MatCardContent, | ||
], | ||
}) | ||
export class FibreChannelPortCardComponent { | ||
readonly port = input.required<FibreChannelPort>(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
...pp/pages/sharing/iscsi/target/all-targets/target-details/target-details.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { createComponentFactory, Spectator } from '@ngneat/spectator/jest'; | ||
import { MockComponents } from 'ng-mocks'; | ||
import { of } from 'rxjs'; | ||
import { mockApi, mockCall } from 'app/core/testing/utils/mock-api.utils'; | ||
import { IscsiTargetMode } from 'app/enums/iscsi.enum'; | ||
import { FibreChannelPort } from 'app/interfaces/fibre-channel.interface'; | ||
import { IscsiTarget } from 'app/interfaces/iscsi.interface'; | ||
import { | ||
AuthorizedNetworksCardComponent, | ||
} from 'app/pages/sharing/iscsi/target/all-targets/target-details/authorized-networks-card/authorized-networks-card.component'; | ||
import { | ||
FibreChannelPortCardComponent, | ||
} from 'app/pages/sharing/iscsi/target/all-targets/target-details/fibre-channel-port-card/fibre-channel-port-card.component'; | ||
import { ApiService } from 'app/services/websocket/api.service'; | ||
import { TargetDetailsComponent } from './target-details.component'; | ||
|
||
describe('TargetDetailsComponent', () => { | ||
let spectator: Spectator<TargetDetailsComponent>; | ||
let mockApiService: jest.Mocked<ApiService>; | ||
|
||
const mockPort = { | ||
id: 'Port-1', | ||
wwpn: '10:00:00:00:c9:20:00:00', | ||
wwpn_b: '10:00:00:00:c9:20:00:01', | ||
} as unknown as FibreChannelPort; | ||
|
||
const createComponent = createComponentFactory({ | ||
component: TargetDetailsComponent, | ||
declarations: [ | ||
MockComponents(AuthorizedNetworksCardComponent, FibreChannelPortCardComponent), | ||
], | ||
providers: [ | ||
mockApi([ | ||
mockCall('fcport.query', [mockPort]), | ||
mockCall('iscsi.extent.query', []), | ||
mockCall('iscsi.targetextent.query', []), | ||
]), | ||
], | ||
}); | ||
|
||
beforeEach(() => { | ||
spectator = createComponent({ | ||
props: { | ||
target: { | ||
id: 1, | ||
mode: IscsiTargetMode.Both, | ||
auth_networks: ['192.168.1.0/24', '10.0.0.0/24'], | ||
} as IscsiTarget, | ||
}, | ||
}); | ||
|
||
mockApiService = spectator.inject(ApiService); | ||
}); | ||
|
||
it('renders AuthorizedNetworksCardComponent if target has authorized networks', () => { | ||
expect(spectator.query(AuthorizedNetworksCardComponent)).toExist(); | ||
expect(spectator.query(AuthorizedNetworksCardComponent)?.target).toEqual({ | ||
id: 1, | ||
mode: IscsiTargetMode.Both, | ||
auth_networks: ['192.168.1.0/24', '10.0.0.0/24'], | ||
}); | ||
}); | ||
|
||
it('renders FibreChannelPortCardComponent if targetPort is set', () => { | ||
spectator.detectChanges(); | ||
expect(spectator.query(FibreChannelPortCardComponent)).toExist(); | ||
expect(spectator.query(FibreChannelPortCardComponent)?.port).toEqual(mockPort); | ||
}); | ||
|
||
it('does not render FibreChannelPortCardComponent if no targetPort is available', () => { | ||
spectator.component.targetPort.set(null); | ||
spectator.detectChanges(); | ||
|
||
expect(spectator.query(FibreChannelPortCardComponent)).toBeNull(); | ||
}); | ||
|
||
it('calls API to fetch Fibre Channel ports when target ID changes', () => { | ||
mockApiService.call.mockReturnValue(of([])); | ||
spectator.setInput({ | ||
target: { | ||
id: 2, | ||
mode: 'FC', | ||
auth_networks: [], | ||
} as IscsiTarget, | ||
}); | ||
|
||
spectator.detectChanges(); | ||
|
||
expect(mockApiService.call).toHaveBeenCalledWith('fcport.query', [[['target.id', '=', 2]]]); | ||
}); | ||
}); |
46 changes: 44 additions & 2 deletions
46
src/app/pages/sharing/iscsi/target/all-targets/target-details/target-details.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,67 @@ | ||
import { | ||
ChangeDetectionStrategy, Component, computed, input, | ||
ChangeDetectionStrategy, Component, computed, effect, input, | ||
signal, | ||
} from '@angular/core'; | ||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; | ||
import { take } from 'rxjs'; | ||
import { IscsiTargetMode } from 'app/enums/iscsi.enum'; | ||
import { FibreChannelPort } from 'app/interfaces/fibre-channel.interface'; | ||
import { IscsiTarget } from 'app/interfaces/iscsi.interface'; | ||
import { AssociatedExtentsCardComponent } from 'app/pages/sharing/iscsi/target/all-targets/target-details/associated-extents-card/associated-extents-card.component'; | ||
import { | ||
AuthorizedNetworksCardComponent, | ||
} from 'app/pages/sharing/iscsi/target/all-targets/target-details/authorized-networks-card/authorized-networks-card.component'; | ||
import { FibreChannelPortCardComponent } from 'app/pages/sharing/iscsi/target/all-targets/target-details/fibre-channel-port-card/fibre-channel-port-card.component'; | ||
import { ApiService } from 'app/services/websocket/api.service'; | ||
|
||
@UntilDestroy() | ||
@Component({ | ||
selector: 'ix-target-details', | ||
templateUrl: './target-details.component.html', | ||
standalone: true, | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
imports: [ | ||
AuthorizedNetworksCardComponent, | ||
FibreChannelPortCardComponent, | ||
AssociatedExtentsCardComponent, | ||
], | ||
}) | ||
export class TargetDetailsComponent { | ||
readonly target = input.required<IscsiTarget>(); | ||
|
||
protected hasIscsiCards = computed(() => [IscsiTargetMode.Iscsi, IscsiTargetMode.Both].includes(this.target().mode)); | ||
targetPort = signal<FibreChannelPort>(null); | ||
|
||
protected hasIscsiCards = computed(() => [ | ||
IscsiTargetMode.Iscsi, | ||
IscsiTargetMode.Both, | ||
].includes(this.target().mode)); | ||
|
||
protected hasFibreCards = computed(() => [ | ||
IscsiTargetMode.Fc, | ||
IscsiTargetMode.Both, | ||
].includes(this.target().mode)); | ||
|
||
constructor( | ||
private api: ApiService, | ||
) { | ||
effect(() => { | ||
const targetId = this.target().id; | ||
this.targetPort.set(null); | ||
|
||
if (targetId) { | ||
this.getPortByTargetId(targetId); | ||
} | ||
}, { allowSignalWrites: true }); | ||
} | ||
|
||
private getPortByTargetId(id: number): void { | ||
this.api.call('fcport.query', [[['target.id', '=', id]]]) | ||
.pipe( | ||
take(1), | ||
untilDestroyed(this), | ||
) | ||
.subscribe((ports) => { | ||
this.targetPort.set(ports[0] || null); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.