Skip to content

Commit

Permalink
feat: ps - support native api
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibaudAV committed Dec 4, 2024
1 parent df82532 commit 5140735
Show file tree
Hide file tree
Showing 24 changed files with 1,277 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,69 +24,81 @@
{{ description }}
</span>

<span *ngIf="isDisabled" class="header__infoIcon" matTooltip="Policies might not be evaluated" matTooltipPosition="before">
<span
*ngIf="!hasStartAndEndConnectors && !disabledNotYetAvailable"
class="header__infoIcon"
matTooltip="Policies might not be evaluated"
matTooltipPosition="before"
>
<mat-icon svgIcon="gio:info"></mat-icon>
</span>
</div>

<div *ngIf="!isDisabled; else disabledPhaseContent" class="wrapper">
<div class="content">
@for (stepVM of stepsVM; track stepVM._id; let isFirst = $first) {
<div class="content__step">
<!-- Connector -->
<ng-container *ngIf="stepVM.type === 'connectors'">
<div class="content__step__connector">
<span *ngFor="let connector of stepVM.connectors" class="gio-badge-white content__step__connector__badge">
<mat-icon *ngIf="connector.icon" [svgIcon]="connector.icon" class="content__step__connector__badge__icon"></mat-icon>
{{ connector.name }}
</span>
</div>
@if (disabledNotYetAvailable) {
<div class="disabledContent">
<gio-banner-info>
Coming soon
<span gioBannerBody> This feature is not yet available in the current version of the API Studio. Stay tuned for updates. </span>
</gio-banner-info>
</div>
} @else if (hasStartAndEndConnectors) {
<div class="wrapper">
<div class="content">
@for (stepVM of stepsVM; track stepVM._id; let isFirst = $first) {
<div class="content__step">
<!-- Connector -->
<ng-container *ngIf="stepVM.type === 'connectors'">
<div class="content__step__connector">
<span *ngFor="let connector of stepVM.connectors" class="gio-badge-white content__step__connector__badge">
<mat-icon *ngIf="connector.icon" [svgIcon]="connector.icon" class="content__step__connector__badge__icon"></mat-icon>
{{ connector.name }}
</span>
</div>

<!-- Add policy button after first connector -->
<ng-container *ngIf="isFirst">
<mat-icon class="content__step__rightArrow" svgIcon="gio:arrow-right"></mat-icon>
<button [disabled]="readOnly" class="content__step__addBtn" mat-button (click)="onAddPolicy(-1)">
<mat-icon svgIcon="gio:plus"></mat-icon>
</button>
<mat-icon class="content__step__rightArrow" svgIcon="gio:arrow-right"></mat-icon>
<!-- Add policy button after first connector -->
<ng-container *ngIf="isFirst">
<mat-icon class="content__step__rightArrow" svgIcon="gio:arrow-right"></mat-icon>
<button [disabled]="readOnly" class="content__step__addBtn" mat-button (click)="onAddPolicy(-1)">
<mat-icon svgIcon="gio:plus"></mat-icon>
</button>
<mat-icon class="content__step__rightArrow" svgIcon="gio:arrow-right"></mat-icon>
</ng-container>
</ng-container>
</ng-container>

<!-- Policy -->
@if (stepVM.type === 'step') {
<div class="content__step__policy">
<div *ngIf="stepVM.step?.condition" class="content__step__policy__condition">
<span class="gio-badge-neutral" [matTooltip]="'Condition: ' + stepVM.step.condition"
><mat-icon svgIcon="gio:if"></mat-icon> {{ stepVM.step.condition }}</span
>
</div>
<!-- Policy -->
@if (stepVM.type === 'step') {
<div class="content__step__policy">
<div *ngIf="stepVM.step?.condition" class="content__step__policy__condition">
<span class="gio-badge-neutral" [matTooltip]="'Condition: ' + stepVM.step.condition"
><mat-icon svgIcon="gio:if"></mat-icon> {{ stepVM.step.condition }}</span
>
</div>

<gio-ps-flow-details-phase-step
class="content__step__step"
[readOnly]="readOnly"
[class.disabled]="readOnly || !stepVM.step.enabled"
[genericPolicies]="genericPolicies"
[step]="stepVM.step"
[flowPhase]="policyFlowPhase"
(stepChange)="onStepChange(stepVM.index, $event)"
(deleted)="onStepDeleted(stepVM.index)"
(disabled)="onStepDisabled(stepVM.index)"
></gio-ps-flow-details-phase-step>
</div>
<gio-ps-flow-details-phase-step
class="content__step__step"
[readOnly]="readOnly"
[class.disabled]="readOnly || !stepVM.step.enabled"
[genericPolicies]="genericPolicies"
[step]="stepVM.step"
[flowPhase]="policyFlowPhase"
(stepChange)="onStepChange(stepVM.index, $event)"
(deleted)="onStepDeleted(stepVM.index)"
(disabled)="onStepDisabled(stepVM.index)"
></gio-ps-flow-details-phase-step>
</div>

<!-- Add policy button -->
<mat-icon class="content__step__rightArrow" svgIcon="gio:arrow-right"></mat-icon>
<button [disabled]="readOnly" class="content__step__addBtn" mat-button (click)="onAddPolicy(stepVM.index)">
<mat-icon svgIcon="gio:plus"></mat-icon>
</button>
<mat-icon class="content__step__rightArrow" svgIcon="gio:arrow-right"></mat-icon>
}
</div>
}
<!-- Add policy button -->
<mat-icon class="content__step__rightArrow" svgIcon="gio:arrow-right"></mat-icon>
<button [disabled]="readOnly" class="content__step__addBtn" mat-button (click)="onAddPolicy(stepVM.index)">
<mat-icon svgIcon="gio:plus"></mat-icon>
</button>
<mat-icon class="content__step__rightArrow" svgIcon="gio:arrow-right"></mat-icon>
}
</div>
}
</div>
</div>
</div>

<ng-template #disabledPhaseContent>
} @else {
<div class="disabledContent">
<gio-banner-warning>
Policies might not be evaluated
Expand All @@ -96,4 +108,4 @@
</span>
</gio-banner-warning>
</div>
</ng-template>
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,15 @@ export class GioPolicyStudioDetailsPhaseComponent implements OnChanges {
@Input()
public trialUrl?: string;

@Input()
public disabledNotYetAvailable = false;

@Output()
public stepsChange = new EventEmitter<Step[]>();

public stepsVM: StepVM[] = [];

public isDisabled = false;

public hasStartAndEndConnectors = true;
constructor(private readonly matDialog: MatDialog) {}

public ngOnChanges(changes: SimpleChanges): void {
Expand Down Expand Up @@ -123,7 +125,7 @@ export class GioPolicyStudioDetailsPhaseComponent implements OnChanges {
];

// Disable phase if there are no start & end connectors
this.isDisabled = this.stepsVM.filter(step => step.type === 'connectors' && !isEmpty(step.connectors)).length < 2;
this.hasStartAndEndConnectors = this.stepsVM.filter(step => step.type === 'connectors' && !isEmpty(step.connectors)).length >= 2;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ import { GioPolicyStudioStepEditDialogHarness } from '../step-edit-dialog/gio-ps
import { GioPolicyStudioPoliciesCatalogDialogHarness } from '../policies-catalog-dialog/gio-ps-policies-catalog-dialog.harness';
import { StepForm } from '../step-form/gio-ps-step-form.harness';

export type PhaseType = 'REQUEST' | 'RESPONSE' | 'PUBLISH' | 'SUBSCRIBE';
export type PhaseType = 'INTERACT' | 'REQUEST' | 'RESPONSE' | 'PUBLISH' | 'SUBSCRIBE';

export type GioPolicyStudioDetailsPhaseHarnessFilters = BaseHarnessFilters & {
type?: PhaseType;
};

const TYPE_TO_TEXT: Record<PhaseType, string> = {
INTERACT: 'Interact phase',
REQUEST: 'Request phase',
RESPONSE: 'Response phase',
PUBLISH: 'Publish phase',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,71 @@
(stepsChange)="onStepsChange('response', $event)"
></gio-ps-flow-details-phase>
</ng-container>

<mat-tab-group *ngIf="apiType === 'NATIVE'" class="content__tabs" dynamicHeight>
<mat-tab label="Global" bodyClass="content__tabs__body">
<gio-ps-flow-details-phase
class="content__phase"
name="Connect phase"
description="Policies will be applied when the client connects to the Gateway"
[disabledNotYetAvailable]="true"
[readOnly]="readOnly"
[startConnector]="endpointsInfo | gioFilterConnectorsByMode: 'CONNECT'"
[endConnector]="entrypointsInfo | gioFilterConnectorsByMode: 'CONNECT'"
[steps]="flow.connect ?? []"
[apiType]="apiType"
[genericPolicies]="genericPolicies"
[trialUrl]="trialUrl"
policyFlowPhase="CONNECT"
(stepsChange)="onStepsChange('connect', $event)"
>
</gio-ps-flow-details-phase>
<gio-ps-flow-details-phase
class="content__phase"
name="Interact phase"
description="Policies will be applied on all interactions between the client and the Gateway"
[readOnly]="readOnly"
[startConnector]="endpointsInfo | gioFilterConnectorsByMode: 'INTERACT'"
[endConnector]="entrypointsInfo | gioFilterConnectorsByMode: 'INTERACT'"
[steps]="flow.interact ?? []"
[apiType]="apiType"
[genericPolicies]="genericPolicies"
[trialUrl]="trialUrl"
policyFlowPhase="INTERACT"
(stepsChange)="onStepsChange('interact', $event)"
></gio-ps-flow-details-phase>
</mat-tab>
<mat-tab label="Event messages" bodyClass="content__tabs__body">
<gio-ps-flow-details-phase
class="content__phase"
name="Publish phase"
description="Policies will be applied when publishing messages"
[readOnly]="readOnly"
[startConnector]="endpointsInfo | gioFilterConnectorsByMode: 'PUBLISH'"
[endConnector]="entrypointsInfo | gioFilterConnectorsByMode: 'PUBLISH'"
[steps]="flow.publish ?? []"
[apiType]="apiType"
[genericPolicies]="genericPolicies"
[trialUrl]="trialUrl"
policyFlowPhase="PUBLISH"
(stepsChange)="onStepsChange('publish', $event)"
></gio-ps-flow-details-phase>
<gio-ps-flow-details-phase
class="content__phase"
name="Subscribe phase"
description="Policies will be applied when fetching messages"
[readOnly]="readOnly"
[startConnector]="endpointsInfo | gioFilterConnectorsByMode: 'SUBSCRIBE'"
[endConnector]="entrypointsInfo | gioFilterConnectorsByMode: 'SUBSCRIBE'"
[steps]="flow.subscribe ?? []"
[apiType]="apiType"
[genericPolicies]="genericPolicies"
[trialUrl]="trialUrl"
policyFlowPhase="SUBSCRIBE"
(stepsChange)="onStepsChange('subscribe', $event)"
></gio-ps-flow-details-phase>
</mat-tab>
</mat-tab-group>
</div>
</ng-container>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from
import { MatDialog } from '@angular/material/dialog';
import { tap } from 'rxjs/operators';
import { isEmpty } from 'lodash';
import { GIO_DIALOG_WIDTH, GioIconsModule, GioLoaderModule } from '@gravitee/ui-particles-angular';
import { GIO_DIALOG_WIDTH, GioBannerModule, GioIconsModule, GioLoaderModule } from '@gravitee/ui-particles-angular';
import { MatTabsModule } from '@angular/material/tabs';
import { MatButtonModule } from '@angular/material/button';
import { CommonModule } from '@angular/common';
Expand All @@ -37,6 +37,10 @@ import { GioPolicyStudioFlowFormDialogResult } from '../flow-form-dialog/gio-ps-
import { GioPolicyStudioDetailsPhaseComponent } from '../flow-details-phase/gio-ps-flow-details-phase.component';
import { GioFilterConnectorsByModePipe } from '../filter-pipe/gio-flter-connectors-by-mode.pipe';
import { GioPolicyStudioDetailsInfoBarComponent } from '../flow-details-info-bar/gio-ps-flow-details-info-bar.component';
import {
GioPolicyStudioFlowNativeFormDialogComponent,
GioPolicyStudioFlowNativeFormDialogData,
} from '../flow-form-dialog/flow-native-form-dialog/gio-ps-flow-native-form-dialog.component';

@Component({
standalone: true,
Expand All @@ -50,6 +54,7 @@ import { GioPolicyStudioDetailsInfoBarComponent } from '../flow-details-info-bar
GioLoaderModule,
GioPolicyStudioDetailsInfoBarComponent,
MatTooltipModule,
GioBannerModule,
],
selector: 'gio-ps-flow-details',
templateUrl: './gio-ps-flow-details.component.html',
Expand Down Expand Up @@ -117,36 +122,59 @@ export class GioPolicyStudioDetailsComponent implements OnChanges {
}

public onEditFlow(): void {
const dialogResult =
this.apiType === 'MESSAGE'
? this.matDialog
.open<
GioPolicyStudioFlowMessageFormDialogComponent,
GioPolicyStudioFlowMessageFormDialogData,
GioPolicyStudioFlowFormDialogResult
>(GioPolicyStudioFlowMessageFormDialogComponent, {
let dialogResult;
switch (this.apiType) {
case 'MESSAGE':
dialogResult = this.matDialog
.open<
GioPolicyStudioFlowMessageFormDialogComponent,
GioPolicyStudioFlowMessageFormDialogData,
GioPolicyStudioFlowFormDialogResult
>(GioPolicyStudioFlowMessageFormDialogComponent, {
data: {
flow: this.flow,
entrypoints: this.entrypointsInfo ?? [],
},
role: 'alertdialog',
id: 'gioPsFlowMessageFormDialog',
width: GIO_DIALOG_WIDTH.MEDIUM,
})
.afterClosed();
break;
case 'PROXY':
dialogResult = this.matDialog
.open<GioPolicyStudioFlowProxyFormDialogComponent, GioPolicyStudioFlowProxyFormDialogData, GioPolicyStudioFlowFormDialogResult>(
GioPolicyStudioFlowProxyFormDialogComponent,
{
data: {
flow: this.flow,
entrypoints: this.entrypointsInfo ?? [],
},
role: 'alertdialog',
id: 'gioPsFlowMessageFormDialog',
id: 'gioPsFlowProxyFormDialog',
width: GIO_DIALOG_WIDTH.MEDIUM,
})
.afterClosed()
: this.matDialog
.open<GioPolicyStudioFlowProxyFormDialogComponent, GioPolicyStudioFlowProxyFormDialogData, GioPolicyStudioFlowFormDialogResult>(
GioPolicyStudioFlowProxyFormDialogComponent,
{
data: {
flow: this.flow,
},
role: 'alertdialog',
id: 'gioPsFlowProxyFormDialog',
width: GIO_DIALOG_WIDTH.MEDIUM,
},
)
.afterClosed();
break;
case 'NATIVE':
dialogResult = this.matDialog
.open<GioPolicyStudioFlowNativeFormDialogComponent, GioPolicyStudioFlowNativeFormDialogData, GioPolicyStudioFlowFormDialogResult>(
GioPolicyStudioFlowNativeFormDialogComponent,
{
data: {
flow: this.flow,
parentGroupName: this.flow!._parentFlowGroupName,
},
)
.afterClosed();
role: 'alertdialog',
id: 'gioPsFlowNativeFormDialog',
width: GIO_DIALOG_WIDTH.MEDIUM,
},
)
.afterClosed();
break;
default:
throw new Error(`Unsupported API type ${this.apiType}`);
}

dialogResult
.pipe(
Expand Down Expand Up @@ -176,7 +204,7 @@ export class GioPolicyStudioDetailsComponent implements OnChanges {
});
}

public onStepsChange(flowPhase: 'request' | 'response' | 'publish' | 'subscribe', steps: Step[]): void {
public onStepsChange(flowPhase: 'connect' | 'interact' | 'request' | 'response' | 'publish' | 'subscribe', steps: Step[]): void {
if (!this.flow) {
return;
}
Expand Down
Loading

0 comments on commit 5140735

Please sign in to comment.