mirror of
https://github.com/zitadel/zitadel.git
synced 2025-11-01 00:46:23 +00:00
# Which Problems Are Solved Actions V2 Method names got cut off in the creation dropdown <img width="668" height="717" alt="old modal" src="https://github.com/user-attachments/assets/e3dda16d-5326-464e-abc7-67a8b146037c" /> # How the Problems Are Solved The modal now first requires a Service to be set and only afterwards are users allowed set Methods. This way we can cut out the Service-Names from the Method-Name leading to cleaner and shorter names. <img width="796" height="988" alt="new modal" src="https://github.com/user-attachments/assets/5002afdf-b639-44ef-954a-5482cca12f96" /> # Additional Changes Changed the Modal dataloading to use Tanstack Query # Additional Context - Closes #10596
This commit is contained in:
@@ -72,7 +72,7 @@ export class ActionsTwoActionsComponent {
|
||||
.open<ActionTwoAddActionDialogComponent, ActionTwoAddActionDialogData, ActionTwoAddActionDialogResult>(
|
||||
ActionTwoAddActionDialogComponent,
|
||||
{
|
||||
width: '400px',
|
||||
width: '500px',
|
||||
data: execution
|
||||
? {
|
||||
execution,
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ label | translate }}</cnsl-label>
|
||||
<input #input cnslInput type="text" placeholder="" [formControl]="control" [matAutocomplete]="autocomplete" />
|
||||
|
||||
<mat-autocomplete requireSelection #autocomplete="matAutocomplete">
|
||||
<mat-option *ngIf="items === undefined" class="is-loading">
|
||||
<mat-spinner diameter="30"></mat-spinner>
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let item of items | filter: input | async" [value]="item">
|
||||
<span>{{ item }}</span>
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
|
||||
<ng-content></ng-content>
|
||||
</cnsl-form-field>
|
||||
@@ -0,0 +1,57 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, Pipe, PipeTransform } from '@angular/core';
|
||||
import { AsyncPipe, NgForOf, NgIf } from '@angular/common';
|
||||
import { FormFieldModule } from 'src/app/modules/form-field/form-field.module';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
import { LabelModule } from 'src/app/modules/label/label.module';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatOptionModule } from '@angular/material/core';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
||||
import { fromEvent, map, mergeWith, Observable } from 'rxjs';
|
||||
import { startWith } from 'rxjs/operators';
|
||||
|
||||
@Pipe({ standalone: true, name: 'filter' })
|
||||
class Filter implements PipeTransform {
|
||||
transform(items: string[] | undefined = [], input: HTMLInputElement): Observable<string[]> {
|
||||
const focus$ = fromEvent(input, 'focus').pipe(map(() => ''));
|
||||
|
||||
return fromEvent(input, 'input').pipe(
|
||||
startWith(undefined),
|
||||
map(() => input.value.toLowerCase()),
|
||||
mergeWith(focus$),
|
||||
map((input) => items.filter((item) => item.toLowerCase().includes(input))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-actions-two-add-action-autocomplete-input',
|
||||
templateUrl: './actions-two-add-action-autocomplete-input.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [
|
||||
AsyncPipe,
|
||||
Filter,
|
||||
FormFieldModule,
|
||||
InputModule,
|
||||
LabelModule,
|
||||
MatAutocompleteModule,
|
||||
MatOptionModule,
|
||||
MatProgressSpinnerModule,
|
||||
TranslateModule,
|
||||
NgIf,
|
||||
NgForOf,
|
||||
ReactiveFormsModule,
|
||||
],
|
||||
})
|
||||
export class ActionsTwoAddActionAutocompleteInputComponent {
|
||||
@Input({ required: true })
|
||||
public label!: string;
|
||||
|
||||
@Input({ required: true })
|
||||
public items: string[] | undefined;
|
||||
|
||||
@Input({ required: true })
|
||||
public control!: FormControl<string>;
|
||||
}
|
||||
@@ -14,68 +14,31 @@
|
||||
</div>
|
||||
|
||||
<p class="condition-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_SERVICE.TITLE' | translate }}</p>
|
||||
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_SERVICE.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input
|
||||
cnslInput
|
||||
type="text"
|
||||
placeholder=""
|
||||
[formControl]="form.form.controls.service"
|
||||
[matAutocomplete]="autoservice"
|
||||
/>
|
||||
|
||||
<mat-autocomplete #autoservice="matAutocomplete">
|
||||
<mat-option *ngIf="(executionServices$ | async) === null" class="is-loading">
|
||||
<mat-spinner diameter="30"></mat-spinner>
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let service of executionServices$ | async" [value]="service">
|
||||
<span>{{ service }}</span>
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</cnsl-form-field>
|
||||
<cnsl-actions-two-add-action-autocomplete-input
|
||||
label="ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_SERVICE.DESCRIPTION"
|
||||
[items]="listExecutionServicesQuery.data()"
|
||||
[control]="form.form.controls.service"
|
||||
></cnsl-actions-two-add-action-autocomplete-input>
|
||||
|
||||
<p class="condition-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_METHOD.TITLE' | translate }}</p>
|
||||
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_METHOD.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input cnslInput type="text" placeholder="" [formControl]="form.form.controls.method" [matAutocomplete]="automethod" />
|
||||
|
||||
<mat-autocomplete #automethod="matAutocomplete">
|
||||
<mat-option *ngIf="(executionMethods$ | async) === null" class="is-loading">
|
||||
<mat-spinner diameter="30"></mat-spinner>
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let method of executionMethods$ | async" [value]="method">
|
||||
<span>{{ method }}</span>
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</cnsl-form-field>
|
||||
<cnsl-actions-two-add-action-autocomplete-input
|
||||
label="ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_METHOD.DESCRIPTION"
|
||||
[items]="filteredExecutionMethods()"
|
||||
[control]="form.form.controls.method"
|
||||
></cnsl-actions-two-add-action-autocomplete-input>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="form.case === 'function'">
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.FUNCTIONNAME.TITLE' | translate }}</cnsl-label>
|
||||
<input
|
||||
cnslInput
|
||||
type="text"
|
||||
placeholder=""
|
||||
[formControl]="form.form.controls.name"
|
||||
[matAutocomplete]="autofunctionname"
|
||||
/>
|
||||
|
||||
<mat-autocomplete #autofunctionname="matAutocomplete">
|
||||
<mat-option *ngIf="(executionFunctions$ | async) === null" class="is-loading">
|
||||
<mat-spinner diameter="30"></mat-spinner>
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let function of executionFunctions$ | async" [value]="function">
|
||||
<span>{{ function }}</span>
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
|
||||
<cnsl-actions-two-add-action-autocomplete-input
|
||||
label="ACTIONSTWO.EXECUTION.DIALOG.CONDITION.FUNCTIONNAME.TITLE"
|
||||
[items]="listExecutionFunctionsQuery.data()"
|
||||
[control]="form.form.controls.name"
|
||||
>
|
||||
<span class="name-hint cnsl-secondary-text" cnslHint>{{
|
||||
'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.FUNCTIONNAME.DESCRIPTION' | translate
|
||||
}}</span>
|
||||
</cnsl-form-field>
|
||||
</cnsl-actions-two-add-action-autocomplete-input>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="form.case === 'event'">
|
||||
@@ -94,14 +57,14 @@
|
||||
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_GROUP.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input cnslInput type="text" placeholder="" #nameInput [formControl]="form.form.controls.group" />
|
||||
<input cnslInput type="text" placeholder="" [formControl]="form.form.controls.group" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<p class="condition-description">{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_EVENT.TITLE' | translate }}</p>
|
||||
|
||||
<cnsl-form-field class="full-width">
|
||||
<cnsl-label>{{ 'ACTIONSTWO.EXECUTION.DIALOG.CONDITION.SELECT_EVENT.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input cnslInput type="text" placeholder="" #nameInput [formControl]="form.form.controls.event" />
|
||||
<input cnslInput type="text" placeholder="" [formControl]="form.form.controls.event" />
|
||||
</cnsl-form-field>
|
||||
</ng-container>
|
||||
|
||||
|
||||
@@ -1,43 +1,24 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, DestroyRef, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, computed, effect, EventEmitter, Input, Output, Signal } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
import {
|
||||
AbstractControl,
|
||||
FormBuilder,
|
||||
FormControl,
|
||||
FormGroup,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
ValidationErrors,
|
||||
ValidatorFn,
|
||||
} from '@angular/forms';
|
||||
import {
|
||||
Observable,
|
||||
catchError,
|
||||
defer,
|
||||
map,
|
||||
of,
|
||||
shareReplay,
|
||||
ReplaySubject,
|
||||
ObservedValueOf,
|
||||
switchMap,
|
||||
combineLatestWith,
|
||||
OperatorFunction,
|
||||
} from 'rxjs';
|
||||
import { FormBuilder, FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { Observable, of, shareReplay, ReplaySubject, ObservedValueOf, switchMap, Subject } from 'rxjs';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { ActionService } from 'src/app/services/action.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { atLeastOneFieldValidator, requiredValidator } from 'src/app/modules/form-field/validators/validators';
|
||||
import { Message } from '@bufbuild/protobuf';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { Condition } from '@zitadel/proto/zitadel/action/v2beta/execution_pb';
|
||||
import { startWith } from 'rxjs/operators';
|
||||
import { distinctUntilChanged, startWith, takeUntil } from 'rxjs/operators';
|
||||
import { CreateQueryResult } from '@tanstack/angular-query-experimental';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { ActionsTwoAddActionAutocompleteInputComponent } from '../actions-two-add-action-autocomplete-input/actions-two-add-action-autocomplete-input.component';
|
||||
|
||||
export type ConditionType = NonNullable<Condition['conditionType']['case']>;
|
||||
export type ConditionTypeValue<T extends ConditionType> = Omit<
|
||||
@@ -64,32 +45,73 @@ export type ConditionTypeValue<T extends ConditionType> = Omit<
|
||||
CommonModule,
|
||||
MatButtonModule,
|
||||
MatProgressSpinnerModule,
|
||||
ActionsTwoAddActionAutocompleteInputComponent,
|
||||
],
|
||||
})
|
||||
export class ActionsTwoAddActionConditionComponent<T extends ConditionType = ConditionType> {
|
||||
@Input({ required: true }) public set conditionType(conditionType: T) {
|
||||
this.conditionType$.next(conditionType);
|
||||
}
|
||||
|
||||
@Output() public readonly back = new EventEmitter<void>();
|
||||
@Output() public readonly continue = new EventEmitter<ConditionTypeValue<T>>();
|
||||
|
||||
private readonly conditionType$ = new ReplaySubject<T>(1);
|
||||
protected readonly form$: ReturnType<typeof this.buildForm>;
|
||||
|
||||
protected readonly executionServices$: Observable<string[]>;
|
||||
protected readonly executionMethods$: Observable<string[]>;
|
||||
protected readonly executionFunctions$: Observable<string[]>;
|
||||
protected readonly listExecutionServicesQuery = this.actionService.listExecutionServicesQuery();
|
||||
private readonly listExecutionMethodsQuery = this.actionService.listExecutionMethodsQuery();
|
||||
protected readonly listExecutionFunctionsQuery = this.actionService.listExecutionFunctionsQuery();
|
||||
protected readonly filteredExecutionMethods: Signal<string[] | undefined>;
|
||||
|
||||
constructor(
|
||||
private readonly fb: FormBuilder,
|
||||
private readonly actionService: ActionService,
|
||||
private readonly toast: ToastService,
|
||||
private readonly destroyRef: DestroyRef,
|
||||
) {
|
||||
this.form$ = this.buildForm().pipe(shareReplay({ refCount: true, bufferSize: 1 }));
|
||||
this.executionServices$ = this.listExecutionServices(this.form$).pipe(shareReplay({ refCount: true, bufferSize: 1 }));
|
||||
this.executionMethods$ = this.listExecutionMethods(this.form$).pipe(shareReplay({ refCount: true, bufferSize: 1 }));
|
||||
this.executionFunctions$ = this.listExecutionFunctions(this.form$).pipe(shareReplay({ refCount: true, bufferSize: 1 }));
|
||||
|
||||
this.handleError(this.listExecutionServicesQuery);
|
||||
this.handleError(this.listExecutionMethodsQuery);
|
||||
this.handleError(this.listExecutionFunctionsQuery);
|
||||
|
||||
this.filteredExecutionMethods = this.filterExecutionMethods(this.form$);
|
||||
}
|
||||
|
||||
public handleError(query: CreateQueryResult<any>) {
|
||||
return effect(() => {
|
||||
const error = query.error();
|
||||
if (error) {
|
||||
this.toast.showError(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private filterExecutionMethods(form$: typeof this.form$) {
|
||||
const service$ = form$.pipe(
|
||||
switchMap((form) => {
|
||||
if (!('service' in form.form.controls)) {
|
||||
return of<string>('');
|
||||
}
|
||||
const { service } = form.form.controls;
|
||||
return service.valueChanges.pipe(startWith(service.value));
|
||||
}),
|
||||
);
|
||||
|
||||
const serviceSignal = toSignal(service$, { initialValue: '' });
|
||||
|
||||
const query = this.actionService.listExecutionMethodsQuery();
|
||||
|
||||
return computed(() => {
|
||||
const methods = query.data();
|
||||
const service = serviceSignal();
|
||||
|
||||
if (!methods) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return methods.filter((method) => method.includes(service)).map((method) => method.replace(`/${service}/`, ''));
|
||||
});
|
||||
}
|
||||
|
||||
public buildForm() {
|
||||
@@ -126,15 +148,20 @@ export class ActionsTwoAddActionConditionComponent<T extends ConditionType = Con
|
||||
obs.next(form);
|
||||
|
||||
const { all, service, method } = form.form.controls;
|
||||
return all.valueChanges
|
||||
.pipe(
|
||||
map(() => all.value),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
)
|
||||
.subscribe((all) => {
|
||||
this.toggleFormControl(service, !all);
|
||||
this.toggleFormControl(method, !all);
|
||||
|
||||
const destroy$ = new Subject<void>();
|
||||
form.form.valueChanges
|
||||
.pipe(distinctUntilChanged(undefined!, JSON.stringify), startWith(undefined), takeUntil(destroy$))
|
||||
.subscribe(() => {
|
||||
this.toggleFormControl(service, !all.value);
|
||||
this.toggleFormControl(method, !!service.value && !all.value);
|
||||
});
|
||||
|
||||
service.valueChanges.pipe(distinctUntilChanged(), takeUntil(destroy$)).subscribe(() => {
|
||||
method.setValue('');
|
||||
});
|
||||
|
||||
return () => destroy$.next();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -162,15 +189,10 @@ export class ActionsTwoAddActionConditionComponent<T extends ConditionType = Con
|
||||
obs.next(form);
|
||||
|
||||
const { all, group, event } = form.form.controls;
|
||||
return all.valueChanges
|
||||
.pipe(
|
||||
map(() => all.value),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
)
|
||||
.subscribe((all) => {
|
||||
this.toggleFormControl(group, !all);
|
||||
this.toggleFormControl(event, !all);
|
||||
});
|
||||
return all.valueChanges.subscribe(() => {
|
||||
this.toggleFormControl(group, !all.value);
|
||||
this.toggleFormControl(event, !all.value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -182,86 +204,6 @@ export class ActionsTwoAddActionConditionComponent<T extends ConditionType = Con
|
||||
}
|
||||
}
|
||||
|
||||
private listExecutionServices(form$: typeof this.form$) {
|
||||
return defer(() => this.actionService.listExecutionServices({})).pipe(
|
||||
map(({ services }) => services),
|
||||
this.formFilter(form$, (form) => {
|
||||
if ('service' in form.form.controls) {
|
||||
return form.form.controls.service;
|
||||
}
|
||||
return undefined;
|
||||
}),
|
||||
catchError((error) => {
|
||||
this.toast.showError(error);
|
||||
return of([]);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private listExecutionFunctions(form$: typeof this.form$) {
|
||||
return defer(() => this.actionService.listExecutionFunctions({})).pipe(
|
||||
map(({ functions }) => functions),
|
||||
this.formFilter(form$, (form) => {
|
||||
if (form.case !== 'function') {
|
||||
return undefined;
|
||||
}
|
||||
return form.form.controls.name;
|
||||
}),
|
||||
catchError((error) => {
|
||||
this.toast.showError(error);
|
||||
return of([]);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private listExecutionMethods(form$: typeof this.form$) {
|
||||
return defer(() => this.actionService.listExecutionMethods({})).pipe(
|
||||
map(({ methods }) => methods),
|
||||
this.formFilter(form$, (form) => {
|
||||
if ('method' in form.form.controls) {
|
||||
return form.form.controls.method;
|
||||
}
|
||||
return undefined;
|
||||
}),
|
||||
// we also filter by service name
|
||||
this.formFilter(form$, (form) => {
|
||||
if ('service' in form.form.controls) {
|
||||
return form.form.controls.service;
|
||||
}
|
||||
return undefined;
|
||||
}),
|
||||
catchError((error) => {
|
||||
this.toast.showError(error);
|
||||
return of([]);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private formFilter(
|
||||
form$: typeof this.form$,
|
||||
getter: (form: ObservedValueOf<typeof this.form$>) => FormControl<string> | undefined,
|
||||
): OperatorFunction<string[], string[]> {
|
||||
const filterValue$ = form$.pipe(
|
||||
map(getter),
|
||||
switchMap((control) => {
|
||||
if (!control) {
|
||||
return of('');
|
||||
}
|
||||
|
||||
return control.valueChanges.pipe(
|
||||
startWith(control.value),
|
||||
map((value) => value.toLowerCase()),
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
return (obs) =>
|
||||
obs.pipe(
|
||||
combineLatestWith(filterValue$),
|
||||
map(([values, filterValue]) => values.filter((v) => v.toLowerCase().includes(filterValue))),
|
||||
);
|
||||
}
|
||||
|
||||
protected submit(form: ObservedValueOf<typeof this.form$>) {
|
||||
if (form.case === 'request' || form.case === 'response') {
|
||||
(this as unknown as ActionsTwoAddActionConditionComponent<'request' | 'response'>).submitRequestOrResponse(form);
|
||||
@@ -289,7 +231,7 @@ export class ActionsTwoAddActionConditionComponent<T extends ConditionType = Con
|
||||
this.continue.emit({
|
||||
condition: {
|
||||
case: 'method',
|
||||
value: method,
|
||||
value: `/${service}/${method}`,
|
||||
},
|
||||
});
|
||||
} else if (service) {
|
||||
|
||||
@@ -29,10 +29,10 @@ import { map, startWith } from 'rxjs/operators';
|
||||
import { TypeSafeCellDefModule } from 'src/app/directives/type-safe-cell-def/type-safe-cell-def.module';
|
||||
import { CdkDrag, CdkDragDrop, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { minArrayLengthValidator } from '../../../form-field/validators/validators';
|
||||
import { ProjectRoleChipModule } from '../../../project-role-chip/project-role-chip.module';
|
||||
import { minArrayLengthValidator } from 'src/app/modules/form-field/validators/validators';
|
||||
import { ProjectRoleChipModule } from 'src/app/modules/project-role-chip/project-role-chip.module';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TableActionsModule } from '../../../table-actions/table-actions.module';
|
||||
import { TableActionsModule } from 'src/app/modules/table-actions/table-actions.module';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
|
||||
@@ -23,12 +23,17 @@ import {
|
||||
UpdateTargetRequestSchema,
|
||||
UpdateTargetResponse,
|
||||
} from '@zitadel/proto/zitadel/action/v2beta/action_service_pb';
|
||||
import { UserService } from './user.service';
|
||||
import { injectQuery } from '@tanstack/angular-query-experimental';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ActionService {
|
||||
constructor(private readonly grpcService: GrpcService) {}
|
||||
constructor(
|
||||
private readonly grpcService: GrpcService,
|
||||
private userService: UserService,
|
||||
) {}
|
||||
|
||||
public listTargets(req: MessageInitShape<typeof ListTargetsRequestSchema>): Promise<ListTargetsResponse> {
|
||||
return this.grpcService.actionNew.listTargets(req);
|
||||
@@ -50,24 +55,6 @@ export class ActionService {
|
||||
return this.grpcService.actionNew.updateTarget(req);
|
||||
}
|
||||
|
||||
public listExecutionFunctions(
|
||||
req: MessageInitShape<typeof ListExecutionFunctionsRequestSchema>,
|
||||
): Promise<ListExecutionFunctionsResponse> {
|
||||
return this.grpcService.actionNew.listExecutionFunctions(req);
|
||||
}
|
||||
|
||||
public listExecutionMethods(
|
||||
req: MessageInitShape<typeof ListExecutionMethodsRequestSchema>,
|
||||
): Promise<ListExecutionMethodsResponse> {
|
||||
return this.grpcService.actionNew.listExecutionMethods(req);
|
||||
}
|
||||
|
||||
public listExecutionServices(
|
||||
req: MessageInitShape<typeof ListExecutionServicesRequestSchema>,
|
||||
): Promise<ListExecutionServicesResponse> {
|
||||
return this.grpcService.actionNew.listExecutionServices(req);
|
||||
}
|
||||
|
||||
public listExecutions(req: MessageInitShape<typeof ListExecutionsRequestSchema>): Promise<ListExecutionsResponse> {
|
||||
return this.grpcService.actionNew.listExecutions(req);
|
||||
}
|
||||
@@ -75,4 +62,43 @@ export class ActionService {
|
||||
public setExecution(req: MessageInitShape<typeof SetExecutionRequestSchema>): Promise<SetExecutionResponse> {
|
||||
return this.grpcService.actionNew.setExecution(req);
|
||||
}
|
||||
|
||||
private listExecutionServices(
|
||||
req: MessageInitShape<typeof ListExecutionServicesRequestSchema>,
|
||||
): Promise<ListExecutionServicesResponse> {
|
||||
return this.grpcService.actionNew.listExecutionServices(req);
|
||||
}
|
||||
|
||||
public listExecutionServicesQuery() {
|
||||
return injectQuery(() => ({
|
||||
queryKey: [this.userService.userId(), 'action', 'listExecutionServices'],
|
||||
queryFn: () => this.listExecutionServices({}).then(({ services }) => services),
|
||||
}));
|
||||
}
|
||||
|
||||
private listExecutionMethods(
|
||||
req: MessageInitShape<typeof ListExecutionMethodsRequestSchema>,
|
||||
): Promise<ListExecutionMethodsResponse> {
|
||||
return this.grpcService.actionNew.listExecutionMethods(req);
|
||||
}
|
||||
|
||||
public listExecutionMethodsQuery() {
|
||||
return injectQuery(() => ({
|
||||
queryKey: [this.userService.userId(), 'action', 'listExecutionMethods'],
|
||||
queryFn: () => this.listExecutionMethods({}).then(({ methods }) => methods),
|
||||
}));
|
||||
}
|
||||
|
||||
private listExecutionFunctions(
|
||||
req: MessageInitShape<typeof ListExecutionFunctionsRequestSchema>,
|
||||
): Promise<ListExecutionFunctionsResponse> {
|
||||
return this.grpcService.actionNew.listExecutionFunctions(req);
|
||||
}
|
||||
|
||||
public listExecutionFunctionsQuery() {
|
||||
return injectQuery(() => ({
|
||||
queryKey: [this.userService.userId(), 'action', 'listExecutionFunctions'],
|
||||
queryFn: () => this.listExecutionFunctions({}).then(({ functions }) => functions),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user