-
Notifications
You must be signed in to change notification settings - Fork 961
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #917 from activepieces/feat/custom-auth
feat: custom auth property
- Loading branch information
Showing
16 changed files
with
315 additions
and
12 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
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
65 changes: 65 additions & 0 deletions
65
...ce-input-forms/custom-auth-connection-dialog/custom-auth-connection-dialog.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,65 @@ | ||
<app-dialog-title-template> | ||
<ng-container *ngIf="!dialogData.connectionToUpdate; else editConnectionHeader">New Connection</ng-container> | ||
<ng-template #editConnectionHeader>Edit {{dialogData!.connectionToUpdate?.name}}</ng-template> | ||
</app-dialog-title-template> | ||
|
||
<mat-dialog-content> | ||
|
||
<form class="ap-flex ap-flex-col ap-gap-2 ap-w-[430px]" [formGroup]="settingsForm" (submit)="submit()"> | ||
<mat-form-field class="ap-w-full" appearance="outline"> | ||
<mat-label>Name</mat-label> | ||
<input [matTooltip]="keyTooltip" formControlName="name" matInput type="text" /> | ||
<mat-error *ngIf="settingsForm.controls['name'].invalid"> | ||
<ng-container *ngIf="settingsForm.get('name')!.getError('required'); else patternErrorOrAlreadyUsed"> | ||
Name is required | ||
</ng-container> | ||
<ng-template #patternErrorOrAlreadyUsed> | ||
<ng-container *ngIf="settingsForm.get('name')!.getError('pattern');"> | ||
Name can only contain letters, numbers and underscores | ||
</ng-container> | ||
<ng-container *ngIf="settingsForm.get('name')!.getError('nameUsed');"> | ||
Name is already used | ||
</ng-container> | ||
</ng-template></mat-error> | ||
</mat-form-field> | ||
|
||
<ng-container *ngFor="let prop of dialogData.pieceAuthConfig.customAuthProps |keyvalue"> | ||
<mat-form-field class="ap-w-full" appearance="outline" | ||
*ngIf="prop.value.type === PropertyType.SECRET_TEXT || prop.value.type === PropertyType.SHORT_TEXT || prop.value.type === PropertyType.LONG_TEXT"> | ||
<mat-label>{{prop.value.displayName}}</mat-label> | ||
<input [matTooltip]="prop.value.description||''" [formControlName]="prop.key" matInput | ||
[type]="prop.value.type === PropertyType.SECRET_TEXT? 'password':'text'" /> | ||
<mat-error *ngIf="settingsForm.get(prop.key)!.invalid"> | ||
{{prop.value.displayName}} is required | ||
</mat-error> | ||
</mat-form-field> | ||
<ng-container *ngIf="prop.value.type === PropertyType.STATIC_DROPDOWN"> | ||
<mat-form-field class="ap-w-full" appearance="outline"> | ||
<mat-label> {{prop.value.displayName}}</mat-label> | ||
<mat-select [formControlName]="prop.key" [matTooltip]="prop.value.description" | ||
[compareWith]="dropdownCompareWithFunction"> | ||
<mat-option *ngFor="let opt of prop.value.options!.options" [value]="opt.value"> | ||
{{opt.label}} | ||
</mat-option> | ||
</mat-select> | ||
<mat-error *ngIf="settingsForm.controls[prop.key]!.invalid"> | ||
{{prop.value.displayName}} is required | ||
</mat-error> | ||
</mat-form-field> | ||
</ng-container> | ||
</ng-container> | ||
</form> | ||
</mat-dialog-content> | ||
|
||
<mat-dialog-actions align="end"> | ||
<div class="ap-flex ap-gap-2.5"> | ||
<app-button btnColor="basic" mat-dialog-close btnSize="default"> | ||
Cancel | ||
</app-button> | ||
<app-button cdkFocusInitial btnSize="default" (click)="submit()" btnColor="primary" type="submit" | ||
[loading]="loading"> | ||
Save | ||
</app-button> | ||
</div> | ||
</mat-dialog-actions> | ||
<ng-container *ngIf="upsert$|async"></ng-container> |
134 changes: 134 additions & 0 deletions
134
...iece-input-forms/custom-auth-connection-dialog/custom-auth-connection-dialog.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,134 @@ | ||
import { Component, Inject } from '@angular/core'; | ||
import { | ||
FormBuilder, | ||
FormControl, | ||
UntypedFormGroup, | ||
Validators, | ||
} from '@angular/forms'; | ||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; | ||
import { Store } from '@ngrx/store'; | ||
import { catchError, Observable, of, take, tap } from 'rxjs'; | ||
import { | ||
AppConnection, | ||
AppConnectionType, | ||
CustomAuthConnection, | ||
PropertyType, | ||
UpsertCustomAuthRequest, | ||
} from '@activepieces/shared'; | ||
import { PieceConfig } from '../../../../../../../../../common/components/configs-form/connector-action-or-config'; | ||
import { BuilderSelectors } from '../../../../../../../../store/builder/builder.selector'; | ||
import { ConnectionValidator } from '../../../../../../validators/connectionNameValidator'; | ||
import deepEqual from 'deep-equal'; | ||
import { appConnectionsActions } from '../../../../../../../../store/app-connections/app-connections.action'; | ||
import { AppConnectionsService } from '../../../../../../../../../common/service/app-connections.service'; | ||
import { MatSnackBar } from '@angular/material/snack-bar'; | ||
|
||
export interface CustomAuthDialogData { | ||
pieceAuthConfig: PieceConfig; | ||
pieceName: string; | ||
connectionToUpdate?: CustomAuthConnection; | ||
} | ||
|
||
@Component({ | ||
selector: 'app-custom-auth-connection-dialog', | ||
templateUrl: './custom-auth-connection-dialog.component.html', | ||
}) | ||
export class CustomAuthConnectionDialogComponent { | ||
loading = false; | ||
settingsForm: UntypedFormGroup; | ||
PropertyType = PropertyType; | ||
keyTooltip = | ||
'The ID of this authentication definition. You will need to select this key whenever you want to reuse this authentication.'; | ||
upsert$: Observable<AppConnection | null>; | ||
constructor( | ||
private fb: FormBuilder, | ||
@Inject(MAT_DIALOG_DATA) | ||
public dialogData: CustomAuthDialogData, | ||
private store: Store, | ||
private dialogRef: MatDialogRef<CustomAuthConnectionDialogComponent>, | ||
private appConnectionsService: AppConnectionsService, | ||
private snackBar: MatSnackBar | ||
) { | ||
const props: Record<string, FormControl> = {}; | ||
Object.entries(this.dialogData.pieceAuthConfig.customAuthProps!).forEach( | ||
([propName, prop]) => { | ||
if (prop.required) { | ||
props[propName] = new FormControl('', Validators.required); | ||
} else { | ||
props[propName] = new FormControl(''); | ||
} | ||
} | ||
); | ||
|
||
this.settingsForm = this.fb.group({ | ||
name: new FormControl( | ||
this.dialogData.connectionToUpdate?.name || | ||
this.dialogData.pieceName.replace(/[^A-Za-z0-9_\\-]/g, '_'), | ||
{ | ||
nonNullable: true, | ||
validators: [ | ||
Validators.required, | ||
Validators.pattern('[A-Za-z0-9_\\-]*'), | ||
], | ||
asyncValidators: [ | ||
ConnectionValidator.createValidator( | ||
this.store | ||
.select(BuilderSelectors.selectAllAppConnections) | ||
.pipe(take(1)), | ||
undefined | ||
), | ||
], | ||
} | ||
), | ||
...props, | ||
}); | ||
if (this.dialogData.connectionToUpdate) { | ||
this.settingsForm.patchValue( | ||
this.dialogData.connectionToUpdate.value.props | ||
); | ||
this.settingsForm.get('name')?.disable(); | ||
} | ||
} | ||
dropdownCompareWithFunction = (opt: any, formControlValue: any) => { | ||
return formControlValue && deepEqual(opt, formControlValue); | ||
}; | ||
submit() { | ||
this.settingsForm.markAllAsTouched(); | ||
if (this.settingsForm.valid) { | ||
this.loading = true; | ||
const propsValues = this.settingsForm.getRawValue(); | ||
delete propsValues.name; | ||
const upsertRequest: UpsertCustomAuthRequest = { | ||
appName: this.dialogData.pieceName, | ||
name: this.settingsForm.getRawValue().name, | ||
value: { | ||
type: AppConnectionType.CUSTOM_AUTH, | ||
props: propsValues, | ||
}, | ||
}; | ||
this.upsert$ = this.appConnectionsService.upsert(upsertRequest).pipe( | ||
catchError((err) => { | ||
console.error(err); | ||
this.snackBar.open( | ||
'Connection operation failed please check your console.', | ||
'Close', | ||
{ | ||
panelClass: 'error', | ||
duration: 5000, | ||
} | ||
); | ||
return of(null); | ||
}), | ||
tap((connection) => { | ||
if (connection) { | ||
this.store.dispatch( | ||
appConnectionsActions.upsert({ connection: connection }) | ||
); | ||
this.dialogRef.close(connection); | ||
} | ||
this.loading = false; | ||
}) | ||
); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"name": "@activepieces/framework", | ||
"version": "0.3.3", | ||
"version": "0.3.4", | ||
"type": "commonjs" | ||
} |
21 changes: 21 additions & 0 deletions
21
packages/pieces/framework/src/lib/framework/property/custom-auth-prop.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,21 @@ | ||
import { PropertyType } from "@activepieces/shared"; | ||
import { BasePropertySchema, NumberProperty, SecretTextProperty, ShortTextProperty, TPropertyValue } from "./base-prop"; | ||
import { StaticDropdownProperty } from "./dropdown-prop"; | ||
|
||
type CustomAuthProp = ShortTextProperty<boolean> | SecretTextProperty<boolean> | NumberProperty<boolean> | StaticDropdownProperty<unknown, boolean>; | ||
|
||
export type CustomAuthPropsValue = Record<string, CustomAuthProp['valueSchema']>; | ||
|
||
export type CustomAuthPropertySchema = BasePropertySchema & { | ||
props: Record<string, CustomAuthProp> | ||
} | ||
|
||
export type CustomAuthPropertyValue = { | ||
props: CustomAuthPropsValue, | ||
} | ||
|
||
export type CustomAuthProperty<R extends boolean> = CustomAuthPropertySchema & TPropertyValue< | ||
CustomAuthPropertyValue, | ||
PropertyType.CUSTOM_AUTH, | ||
R | ||
>; |
Oops, something went wrong.