mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-07 07:16:54 +00:00
chore!: Introduce ZITADEL v3 (#9645)
This PR summarizes multiple changes specifically only available with ZITADEL v3: - feat: Web Keys management (https://github.com/zitadel/zitadel/pull/9526) - fix(cmd): ensure proper working of mirror (https://github.com/zitadel/zitadel/pull/9509) - feat(Authz): system user support for permission check v2 (https://github.com/zitadel/zitadel/pull/9640) - chore(license): change from Apache to AGPL (https://github.com/zitadel/zitadel/pull/9597) - feat(console): list v2 sessions (https://github.com/zitadel/zitadel/pull/9539) - fix(console): add loginV2 feature flag (https://github.com/zitadel/zitadel/pull/9682) - fix(feature flags): allow reading "own" flags (https://github.com/zitadel/zitadel/pull/9649) - feat(console): add Actions V2 UI (https://github.com/zitadel/zitadel/pull/9591) BREAKING CHANGE - feat(webkey): migrate to v2beta API (https://github.com/zitadel/zitadel/pull/9445) - chore!: remove CockroachDB Support (https://github.com/zitadel/zitadel/pull/9444) - feat(actions): migrate to v2beta API (https://github.com/zitadel/zitadel/pull/9489) --------- Co-authored-by: Livio Spring <livio.a@gmail.com> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com> Co-authored-by: Ramon <mail@conblem.me> Co-authored-by: Elio Bischof <elio@zitadel.com> Co-authored-by: Kenta Yamaguchi <56732734+KEY60228@users.noreply.github.com> Co-authored-by: Harsha Reddy <harsha.reddy@klaviyo.com> Co-authored-by: Livio Spring <livio@zitadel.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Iraq <66622793+kkrime@users.noreply.github.com> Co-authored-by: Florian Forster <florian@zitadel.com> Co-authored-by: Tim Möhlmann <tim+github@zitadel.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Max Peintner <peintnerm@gmail.com>
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import { ChangeDetectionStrategy, Component, DestroyRef, OnInit } from '@angular/core';
|
||||
import { defer, firstValueFrom, Observable, of, ReplaySubject, shareReplay, Subject, TimeoutError } from 'rxjs';
|
||||
import { ActionService } from 'src/app/services/action.service';
|
||||
import { NewFeatureService } from 'src/app/services/new-feature.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { ORGANIZATIONS } from '../../settings-list/settings';
|
||||
import { catchError, filter, map, startWith, switchMap, timeout } from 'rxjs/operators';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActionTwoAddTargetDialogComponent } from '../actions-two-add-target/actions-two-add-target-dialog.component';
|
||||
import { MessageInitShape } from '@bufbuild/protobuf';
|
||||
import { Target } from '@zitadel/proto/zitadel/action/v2beta/target_pb';
|
||||
import {
|
||||
CreateTargetRequestSchema,
|
||||
UpdateTargetRequestSchema,
|
||||
} from '@zitadel/proto/zitadel/action/v2beta/action_service_pb';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-actions-two-targets',
|
||||
templateUrl: './actions-two-targets.component.html',
|
||||
styleUrls: ['./actions-two-targets.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ActionsTwoTargetsComponent implements OnInit {
|
||||
private readonly actionsEnabled$: Observable<boolean>;
|
||||
protected readonly targets$: Observable<Target[]>;
|
||||
protected readonly refresh$ = new ReplaySubject<true>(1);
|
||||
|
||||
constructor(
|
||||
private readonly actionService: ActionService,
|
||||
private readonly featureService: NewFeatureService,
|
||||
private readonly toast: ToastService,
|
||||
private readonly destroyRef: DestroyRef,
|
||||
private readonly router: Router,
|
||||
private readonly route: ActivatedRoute,
|
||||
private readonly dialog: MatDialog,
|
||||
) {
|
||||
this.actionsEnabled$ = this.getActionsEnabled$().pipe(shareReplay({ refCount: true, bufferSize: 1 }));
|
||||
this.targets$ = this.getTargets$(this.actionsEnabled$);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
// this also preloads
|
||||
this.actionsEnabled$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(async (enabled) => {
|
||||
if (enabled) {
|
||||
return;
|
||||
}
|
||||
await this.router.navigate([], {
|
||||
relativeTo: this.route,
|
||||
queryParams: {
|
||||
id: ORGANIZATIONS.id,
|
||||
},
|
||||
queryParamsHandling: 'merge',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private getTargets$(actionsEnabled$: Observable<boolean>) {
|
||||
return this.refresh$.pipe(
|
||||
startWith(true),
|
||||
switchMap(() => {
|
||||
return this.actionService.listTargets({});
|
||||
}),
|
||||
map(({ result }) => result),
|
||||
catchError(async (err) => {
|
||||
const actionsEnabled = await firstValueFrom(actionsEnabled$);
|
||||
if (actionsEnabled) {
|
||||
this.toast.showError(err);
|
||||
}
|
||||
return [];
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private getActionsEnabled$() {
|
||||
return defer(() => this.featureService.getInstanceFeatures()).pipe(
|
||||
map(({ actions }) => actions?.enabled ?? false),
|
||||
timeout(1000),
|
||||
catchError((err) => {
|
||||
if (!(err instanceof TimeoutError)) {
|
||||
this.toast.showError(err);
|
||||
}
|
||||
return of(false);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
public async deleteTarget(target: Target) {
|
||||
await this.actionService.deleteTarget({ id: target.id });
|
||||
await new Promise((res) => setTimeout(res, 1000));
|
||||
this.refresh$.next(true);
|
||||
}
|
||||
|
||||
public openDialog(target?: Target): void {
|
||||
const ref = this.dialog.open<
|
||||
ActionTwoAddTargetDialogComponent,
|
||||
{ target?: Target },
|
||||
MessageInitShape<typeof UpdateTargetRequestSchema | typeof CreateTargetRequestSchema>
|
||||
>(ActionTwoAddTargetDialogComponent, {
|
||||
width: '550px',
|
||||
data: {
|
||||
target: target,
|
||||
},
|
||||
});
|
||||
|
||||
ref
|
||||
.afterClosed()
|
||||
.pipe(filter(Boolean), takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe(async (dialogResponse) => {
|
||||
if ('id' in dialogResponse) {
|
||||
await this.actionService.updateTarget(dialogResponse);
|
||||
} else {
|
||||
await this.actionService.createTarget(dialogResponse);
|
||||
}
|
||||
|
||||
await new Promise((res) => setTimeout(res, 1000));
|
||||
this.refresh$.next(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user