mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-13 19:09:16 +00:00
perf: query projected milestones for onboarding view (#6760)
* feat: support list milestones api * show milestones in onboarding view * add authenticated milestone * add icon to login milestone * update main * lint * fix import * fix import * lint * reuse proto milestone type mapping
This commit is contained in:
@@ -904,6 +904,7 @@ InternalAuthZ:
|
|||||||
- "project.grant.member.write"
|
- "project.grant.member.write"
|
||||||
- "project.grant.member.delete"
|
- "project.grant.member.delete"
|
||||||
- "events.read"
|
- "events.read"
|
||||||
|
- "milestones.read"
|
||||||
- Role: "IAM_OWNER_VIEWER"
|
- Role: "IAM_OWNER_VIEWER"
|
||||||
Permissions:
|
Permissions:
|
||||||
- "iam.read"
|
- "iam.read"
|
||||||
@@ -929,6 +930,7 @@ InternalAuthZ:
|
|||||||
- "project.grant.read"
|
- "project.grant.read"
|
||||||
- "project.grant.member.read"
|
- "project.grant.member.read"
|
||||||
- "events.read"
|
- "events.read"
|
||||||
|
- "milestones.read"
|
||||||
- Role: "IAM_ORG_MANAGER"
|
- Role: "IAM_ORG_MANAGER"
|
||||||
Permissions:
|
Permissions:
|
||||||
- "org.read"
|
- "org.read"
|
||||||
|
@@ -20,15 +20,18 @@
|
|||||||
[routerLink]="action[1].link"
|
[routerLink]="action[1].link"
|
||||||
[queryParams]="{ id: action[1].fragment }"
|
[queryParams]="{ id: action[1].fragment }"
|
||||||
class="action-element"
|
class="action-element"
|
||||||
[ngClass]="{ done: action[1].event !== undefined }"
|
[ngClass]="{ done: action[1].reached !== undefined }"
|
||||||
>
|
>
|
||||||
<div class="state-circle">
|
<div class="state-circle">
|
||||||
<mat-icon *ngIf="action[1]?.event !== undefined" class="success-icon" matTooltip="{{ action[1].event | event }}"
|
<mat-icon
|
||||||
|
*ngIf="action[1]?.reached !== undefined"
|
||||||
|
class="success-icon"
|
||||||
|
matTooltip="{{ action[1].reached | milestone }}"
|
||||||
>check_circle</mat-icon
|
>check_circle</mat-icon
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="name">{{ 'ONBOARDING.EVENTS.' + action[0] + '.title' | translate }}</span>
|
<span class="name">{{ 'ONBOARDING.MILESTONES.' + action[0] + '.title' | translate }}</span>
|
||||||
<mat-icon class="arrow-right">keyboard_arrow_right</mat-icon>
|
<mat-icon class="arrow-right">keyboard_arrow_right</mat-icon>
|
||||||
</a>
|
</a>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { ONBOARDING_EVENTS } from 'src/app/utils/onboarding';
|
import { ONBOARDING_MILESTONES } from 'src/app/utils/onboarding';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'cnsl-onboarding-card',
|
selector: 'cnsl-onboarding-card',
|
||||||
@@ -11,7 +11,7 @@ import { ONBOARDING_EVENTS } from 'src/app/utils/onboarding';
|
|||||||
export class OnboardingCardComponent implements OnInit {
|
export class OnboardingCardComponent implements OnInit {
|
||||||
public percentageChanged: EventEmitter<number> = new EventEmitter<number>();
|
public percentageChanged: EventEmitter<number> = new EventEmitter<number>();
|
||||||
public loading$: BehaviorSubject<any> = new BehaviorSubject(false);
|
public loading$: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||||
public actions = this.adminService.progressEvents;
|
public actions = this.adminService.progressMilestones;
|
||||||
@Output() public dismissedCard: EventEmitter<void> = new EventEmitter();
|
@Output() public dismissedCard: EventEmitter<void> = new EventEmitter();
|
||||||
|
|
||||||
constructor(public adminService: AdminService) {}
|
constructor(public adminService: AdminService) {}
|
||||||
@@ -21,6 +21,6 @@ export class OnboardingCardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.adminService.loadEvents.next(ONBOARDING_EVENTS);
|
this.adminService.loadMilestones.next(ONBOARDING_MILESTONES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,7 @@ import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/le
|
|||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { EventPipeModule } from 'src/app/pipes/event-pipe/event-pipe.module';
|
import { MilestonePipeModule } from 'src/app/pipes/milestone-pipe/milestone-pipe.module';
|
||||||
import { OnboardingCardComponent } from './onboarding-card.component';
|
import { OnboardingCardComponent } from './onboarding-card.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -17,7 +17,7 @@ import { OnboardingCardComponent } from './onboarding-card.component';
|
|||||||
TranslateModule,
|
TranslateModule,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
EventPipeModule,
|
MilestonePipeModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
],
|
],
|
||||||
exports: [OnboardingCardComponent],
|
exports: [OnboardingCardComponent],
|
||||||
|
@@ -27,10 +27,13 @@
|
|||||||
[routerLink]="action[1].link"
|
[routerLink]="action[1].link"
|
||||||
[queryParams]="{ id: action[1].fragment }"
|
[queryParams]="{ id: action[1].fragment }"
|
||||||
class="action-card card"
|
class="action-card card"
|
||||||
[ngClass]="{ done: action[1].event !== undefined }"
|
[ngClass]="{ done: action[1].reached !== undefined }"
|
||||||
>
|
>
|
||||||
<div class="state-circle">
|
<div class="state-circle">
|
||||||
<mat-icon *ngIf="action[1]?.event !== undefined" matTooltip="{{ action[1].event | event }}" class="success-icon"
|
<mat-icon
|
||||||
|
*ngIf="action[1]?.reached !== undefined"
|
||||||
|
matTooltip="{{ action[1].reached | milestone }}"
|
||||||
|
class="success-icon"
|
||||||
>check_circle</mat-icon
|
>check_circle</mat-icon
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -54,16 +57,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-block">
|
<div class="text-block">
|
||||||
<span class="name">{{ 'ONBOARDING.EVENTS.' + action[0] + '.title' | translate }}</span>
|
<span class="name">{{ 'ONBOARDING.MILESTONES.' + action[0] + '.title' | translate }}</span>
|
||||||
<span class="cnsl-secondary-text description">{{
|
<span class="cnsl-secondary-text description">{{
|
||||||
'ONBOARDING.EVENTS.' + action[0] + '.description' | translate
|
'ONBOARDING.MILESTONES.' + action[0] + '.description' | translate
|
||||||
}}</span>
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
<div class="action-row">
|
<div class="action-row">
|
||||||
<span>{{ 'ONBOARDING.EVENTS.' + action[0] + '.action' | translate }}</span>
|
<span>{{ 'ONBOARDING.MILESTONES.' + action[0] + '.action' | translate }}</span>
|
||||||
<mat-icon class="icon">keyboard_arrow_right</mat-icon>
|
<mat-icon class="icon">keyboard_arrow_right</mat-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { ThemeService } from 'src/app/services/theme.service';
|
import { ThemeService } from 'src/app/services/theme.service';
|
||||||
import { ONBOARDING_EVENTS } from 'src/app/utils/onboarding';
|
import { ONBOARDING_MILESTONES } from 'src/app/utils/onboarding';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'cnsl-onboarding',
|
selector: 'cnsl-onboarding',
|
||||||
@@ -9,12 +9,12 @@ import { ONBOARDING_EVENTS } from 'src/app/utils/onboarding';
|
|||||||
styleUrls: ['./onboarding.component.scss'],
|
styleUrls: ['./onboarding.component.scss'],
|
||||||
})
|
})
|
||||||
export class OnboardingComponent {
|
export class OnboardingComponent {
|
||||||
public actions = this.adminService.progressEvents;
|
public actions = this.adminService.progressMilestones;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public adminService: AdminService,
|
public adminService: AdminService,
|
||||||
public themeService: ThemeService,
|
public themeService: ThemeService,
|
||||||
) {
|
) {
|
||||||
this.adminService.loadEvents.next(ONBOARDING_EVENTS);
|
this.adminService.loadMilestones.next(ONBOARDING_MILESTONES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,7 @@ import { ShortcutsModule } from 'src/app/modules/shortcuts/shortcuts.module';
|
|||||||
|
|
||||||
import { MatLegacyProgressBarModule } from '@angular/material/legacy-progress-bar';
|
import { MatLegacyProgressBarModule } from '@angular/material/legacy-progress-bar';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { EventPipeModule } from 'src/app/pipes/event-pipe/event-pipe.module';
|
import { MilestonePipeModule } from 'src/app/pipes/milestone-pipe/milestone-pipe.module';
|
||||||
import { OnboardingComponent } from './onboarding.component';
|
import { OnboardingComponent } from './onboarding.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -24,7 +24,7 @@ import { OnboardingComponent } from './onboarding.component';
|
|||||||
RouterModule,
|
RouterModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
MatLegacyProgressBarModule,
|
MatLegacyProgressBarModule,
|
||||||
EventPipeModule,
|
MilestonePipeModule,
|
||||||
],
|
],
|
||||||
exports: [OnboardingComponent],
|
exports: [OnboardingComponent],
|
||||||
})
|
})
|
||||||
|
@@ -2,11 +2,11 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { LocalizedDatePipeModule } from '../localized-date-pipe/localized-date-pipe.module';
|
import { LocalizedDatePipeModule } from '../localized-date-pipe/localized-date-pipe.module';
|
||||||
import { TimestampToDatePipeModule } from '../timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
import { TimestampToDatePipeModule } from '../timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
||||||
import { EventPipe } from './event.pipe';
|
import { MilestonePipe } from './milestonePipe';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [EventPipe],
|
declarations: [MilestonePipe],
|
||||||
imports: [CommonModule, TimestampToDatePipeModule, LocalizedDatePipeModule],
|
imports: [CommonModule, TimestampToDatePipeModule, LocalizedDatePipeModule],
|
||||||
exports: [EventPipe],
|
exports: [MilestonePipe],
|
||||||
})
|
})
|
||||||
export class EventPipeModule {}
|
export class MilestonePipeModule {}
|
@@ -1,22 +1,18 @@
|
|||||||
import { Pipe, PipeTransform } from '@angular/core';
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { Event } from 'src/app/proto/generated/zitadel/event_pb';
|
|
||||||
import { LocalizedDatePipe } from '../localized-date-pipe/localized-date.pipe';
|
import { LocalizedDatePipe } from '../localized-date-pipe/localized-date.pipe';
|
||||||
import { TimestampToDatePipe } from '../timestamp-to-date-pipe/timestamp-to-date.pipe';
|
import { TimestampToDatePipe } from '../timestamp-to-date-pipe/timestamp-to-date.pipe';
|
||||||
|
import { Milestone } from '../../proto/generated/zitadel/milestone/v1/milestone_pb';
|
||||||
|
|
||||||
@Pipe({
|
@Pipe({
|
||||||
name: 'event',
|
name: 'milestone',
|
||||||
})
|
})
|
||||||
export class EventPipe implements PipeTransform {
|
export class MilestonePipe implements PipeTransform {
|
||||||
constructor(private translateService: TranslateService) {}
|
constructor(private translateService: TranslateService) {}
|
||||||
|
|
||||||
public transform(event?: Event.AsObject): any {
|
public transform(milestone?: Milestone.AsObject): any {
|
||||||
if (event && event.editor?.displayName && event.creationDate) {
|
if (milestone && milestone.reachedDate) {
|
||||||
const timestampToDate = new TimestampToDatePipe().transform(event.creationDate);
|
const timestampToDate = new TimestampToDatePipe().transform(milestone.reachedDate);
|
||||||
const datePipeOutput = new LocalizedDatePipe(this.translateService).transform(timestampToDate);
|
|
||||||
return `${event.editor?.displayName} last changed it on ${datePipeOutput}`;
|
|
||||||
} else if (event && event.creationDate) {
|
|
||||||
const timestampToDate = new TimestampToDatePipe().transform(event.creationDate);
|
|
||||||
const datePipeOutput = new LocalizedDatePipe(this.translateService).transform(timestampToDate);
|
const datePipeOutput = new LocalizedDatePipe(this.translateService).transform(timestampToDate);
|
||||||
return `done on ${datePipeOutput}`;
|
return `done on ${datePipeOutput}`;
|
||||||
} else {
|
} else {
|
@@ -152,6 +152,8 @@ import {
|
|||||||
ListLoginPolicyMultiFactorsResponse,
|
ListLoginPolicyMultiFactorsResponse,
|
||||||
ListLoginPolicySecondFactorsRequest,
|
ListLoginPolicySecondFactorsRequest,
|
||||||
ListLoginPolicySecondFactorsResponse,
|
ListLoginPolicySecondFactorsResponse,
|
||||||
|
ListMilestonesRequest,
|
||||||
|
ListMilestonesResponse,
|
||||||
ListProvidersRequest,
|
ListProvidersRequest,
|
||||||
ListProvidersResponse,
|
ListProvidersResponse,
|
||||||
ListSecretGeneratorsRequest,
|
ListSecretGeneratorsRequest,
|
||||||
@@ -296,85 +298,77 @@ import { SearchQuery } from '../proto/generated/zitadel/member_pb';
|
|||||||
import { ListQuery } from '../proto/generated/zitadel/object_pb';
|
import { ListQuery } from '../proto/generated/zitadel/object_pb';
|
||||||
import { GrpcService } from './grpc.service';
|
import { GrpcService } from './grpc.service';
|
||||||
import { StorageLocation, StorageService } from './storage.service';
|
import { StorageLocation, StorageService } from './storage.service';
|
||||||
|
import {
|
||||||
|
IsReachedQuery,
|
||||||
|
Milestone,
|
||||||
|
MilestoneQuery,
|
||||||
|
MilestoneType,
|
||||||
|
} from '../proto/generated/zitadel/milestone/v1/milestone_pb';
|
||||||
|
|
||||||
export interface OnboardingActions {
|
export interface OnboardingActions {
|
||||||
order: number;
|
order: number;
|
||||||
eventType: string;
|
milestoneType: MilestoneType;
|
||||||
oneof: string[];
|
link: string;
|
||||||
link: string | string[];
|
|
||||||
fragment?: string | undefined;
|
fragment?: string | undefined;
|
||||||
iconClasses?: string;
|
iconClasses?: string;
|
||||||
darkcolor: string;
|
darkcolor: string;
|
||||||
lightcolor: string;
|
lightcolor: string;
|
||||||
aggregateType: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type OnboardingEvent = {
|
type OnboardingMilestone = {
|
||||||
order: number;
|
order: number;
|
||||||
link: string;
|
link: string;
|
||||||
fragment: string | undefined;
|
fragment: string | undefined;
|
||||||
event: Event.AsObject | undefined;
|
reached: Milestone.AsObject | undefined;
|
||||||
iconClasses?: string;
|
iconClasses?: string;
|
||||||
darkcolor: string;
|
darkcolor: string;
|
||||||
lightcolor: string;
|
lightcolor: string;
|
||||||
};
|
};
|
||||||
type OnboardingEventEntries = Array<[string, OnboardingEvent]> | [];
|
type OnboardingMilestoneEntries = Array<[string, OnboardingMilestone]> | [];
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class AdminService {
|
export class AdminService {
|
||||||
|
private readonly milestoneTypePrefixLength = 'MILESTONE_TYPE_'.length;
|
||||||
public hideOnboarding: boolean = false;
|
public hideOnboarding: boolean = false;
|
||||||
public loadEvents: Subject<OnboardingActions[]> = new Subject();
|
public loadMilestones: Subject<OnboardingActions[]> = new Subject();
|
||||||
public onboardingLoading: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
public onboardingLoading: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||||
public progressEvents$: Observable<OnboardingEventEntries> = this.loadEvents.pipe(
|
public progressMilestones$: Observable<OnboardingMilestoneEntries> = this.loadMilestones.pipe(
|
||||||
tap(() => this.onboardingLoading.next(true)),
|
tap(() => this.onboardingLoading.next(true)),
|
||||||
switchMap((actions) => {
|
switchMap((actions) => {
|
||||||
const searchForTypes = actions.map((oe) => oe.oneof).flat();
|
const milestonesListQuery = new ListQuery();
|
||||||
const aggregateTypes = actions.map((oe) => oe.aggregateType);
|
milestonesListQuery.setAsc(true);
|
||||||
const eventsReq = new ListEventsRequest()
|
milestonesListQuery.setLimit(20);
|
||||||
.setAsc(true)
|
const milestoneIsReachedQuery = new IsReachedQuery().setReached(true);
|
||||||
.setEventTypesList(searchForTypes)
|
const milestonesQuery = new MilestoneQuery().setIsReachedQuery(milestoneIsReachedQuery);
|
||||||
.setAggregateTypesList(aggregateTypes)
|
const milestonesReq = new ListMilestonesRequest().setQuery(milestonesListQuery).setQueriesList([milestonesQuery]);
|
||||||
.setAsc(false);
|
return from(this.listMilestones(milestonesReq)).pipe(
|
||||||
return from(this.listEvents(eventsReq)).pipe(
|
map((reachedMilestones) => {
|
||||||
map((events) => {
|
let obj: { [type: string]: OnboardingMilestone } = {};
|
||||||
const el = events.toObject().eventsList.filter((e) => e.editor?.service !== 'System-API' && e.editor?.userId);
|
|
||||||
|
|
||||||
let obj: { [type: string]: OnboardingEvent } = {};
|
|
||||||
actions.map((action) => {
|
actions.map((action) => {
|
||||||
const filtered = el.filter((event) => event.type?.type && action.oneof.includes(event.type.type));
|
obj[Object.keys(MilestoneType)[action.milestoneType].substring(this.milestoneTypePrefixLength)] = {
|
||||||
(obj as any)[action.eventType] = filtered.length
|
order: action.order,
|
||||||
? {
|
link: action.link,
|
||||||
order: action.order,
|
fragment: action.fragment,
|
||||||
link: action.link,
|
iconClasses: action.iconClasses,
|
||||||
fragment: action.fragment,
|
darkcolor: action.darkcolor,
|
||||||
event: filtered[0],
|
lightcolor: action.lightcolor,
|
||||||
iconClasses: action.iconClasses,
|
reached: reachedMilestones.resultList.find((reached) => {
|
||||||
darkcolor: action.darkcolor,
|
return reached.type.valueOf() == action.milestoneType;
|
||||||
lightcolor: action.lightcolor,
|
}),
|
||||||
}
|
};
|
||||||
: {
|
|
||||||
order: action.order,
|
|
||||||
link: action.link,
|
|
||||||
fragment: action.fragment,
|
|
||||||
event: undefined,
|
|
||||||
iconClasses: action.iconClasses,
|
|
||||||
darkcolor: action.darkcolor,
|
|
||||||
lightcolor: action.lightcolor,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const toArray = Object.entries(obj).sort(([key0, a], [key1, b]) => a.order - b.order);
|
const toArray = Object.entries(obj).sort(([key0, a], [key1, b]) => a.order - b.order);
|
||||||
|
|
||||||
const toDo = toArray.filter(([key, value]) => value.event === undefined);
|
const toDo = toArray.filter(([key, value]) => value.reached === undefined);
|
||||||
const done = toArray.filter(([key, value]) => !!value.event);
|
const done = toArray.filter(([key, value]) => !!value.reached);
|
||||||
|
|
||||||
return [...toDo, ...done];
|
return [...toDo, ...done];
|
||||||
}),
|
}),
|
||||||
tap((events) => {
|
tap((milestones) => {
|
||||||
const total = events.length;
|
const total = milestones.length;
|
||||||
const done = events.map(([type, value]) => value.event !== undefined).filter((res) => !!res).length;
|
const done = milestones.map(([type, value]) => value.reached !== undefined).filter((res) => !!res).length;
|
||||||
const percentage = Math.round((done / total) * 100);
|
const percentage = Math.round((done / total) * 100);
|
||||||
this.progressDone.next(done);
|
this.progressDone.next(done);
|
||||||
this.progressTotal.next(total);
|
this.progressTotal.next(total);
|
||||||
@@ -390,7 +384,9 @@ export class AdminService {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
public progressEvents: BehaviorSubject<OnboardingEventEntries> = new BehaviorSubject<OnboardingEventEntries>([]);
|
public progressMilestones: BehaviorSubject<OnboardingMilestoneEntries> = new BehaviorSubject<OnboardingMilestoneEntries>(
|
||||||
|
[],
|
||||||
|
);
|
||||||
public progressPercentage: BehaviorSubject<number> = new BehaviorSubject(0);
|
public progressPercentage: BehaviorSubject<number> = new BehaviorSubject(0);
|
||||||
public progressDone: BehaviorSubject<number> = new BehaviorSubject(0);
|
public progressDone: BehaviorSubject<number> = new BehaviorSubject(0);
|
||||||
public progressTotal: BehaviorSubject<number> = new BehaviorSubject(0);
|
public progressTotal: BehaviorSubject<number> = new BehaviorSubject(0);
|
||||||
@@ -400,7 +396,7 @@ export class AdminService {
|
|||||||
private readonly grpcService: GrpcService,
|
private readonly grpcService: GrpcService,
|
||||||
private storageService: StorageService,
|
private storageService: StorageService,
|
||||||
) {
|
) {
|
||||||
this.progressEvents$.subscribe(this.progressEvents);
|
this.progressMilestones$.subscribe(this.progressMilestones);
|
||||||
|
|
||||||
this.hideOnboarding =
|
this.hideOnboarding =
|
||||||
this.storageService.getItem('onboarding-dismissed', StorageLocation.local) === 'true' ? true : false;
|
this.storageService.getItem('onboarding-dismissed', StorageLocation.local) === 'true' ? true : false;
|
||||||
@@ -1254,4 +1250,8 @@ export class AdminService {
|
|||||||
|
|
||||||
return this.grpcService.admin.updateIAMMember(req, null).then((resp) => resp.toObject());
|
return this.grpcService.admin.updateIAMMember(req, null).then((resp) => resp.toObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public listMilestones(req: ListMilestonesRequest): Promise<ListMilestonesResponse.AsObject> {
|
||||||
|
return this.grpcService.admin.listMilestones(req, null).then((resp) => resp.toObject());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,8 @@ export const COLORS = [
|
|||||||
{ 500: '#d946ef', 200: '#f5d0fe', 300: '#f0abfc', 600: '#c026d3', 700: '#a21caf', 900: '#701a75' },
|
{ 500: '#d946ef', 200: '#f5d0fe', 300: '#f0abfc', 600: '#c026d3', 700: '#a21caf', 900: '#701a75' },
|
||||||
{ 500: '#ec4899', 200: '#fbcfe8', 300: '#f9a8d4', 600: '#db2777', 700: '#be185d', 900: '#831843' },
|
{ 500: '#ec4899', 200: '#fbcfe8', 300: '#f9a8d4', 600: '#db2777', 700: '#be185d', 900: '#831843' },
|
||||||
{ 500: '#f43f5e', 200: '#fecdd3', 300: '#fda4af', 600: '#e11d48', 700: '#be123c', 900: '#881337' },
|
{ 500: '#f43f5e', 200: '#fecdd3', 300: '#fda4af', 600: '#e11d48', 700: '#be123c', 900: '#881337' },
|
||||||
|
{ 500: '#A89F91', 200: '#D4CDC6', 300: '#BFB6AC', 600: '#8F8378', 700: '#736A60', 900: '#4F4A40' },
|
||||||
|
{ 500: '#BA9F88', 200: '#E8D3C5', 300: '#D4BAA7', 600: '#9C7A68', 700: '#8A6E5D', 900: '#5F4C42' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const WEB_APP_COLOR: Color = COLORS[6];
|
export const WEB_APP_COLOR: Color = COLORS[6];
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { OnboardingActions } from '../services/admin.service';
|
import { OnboardingActions } from '../services/admin.service';
|
||||||
import { COLORS } from './color';
|
import { COLORS } from './color';
|
||||||
|
import { MilestoneType } from '../proto/generated/zitadel/milestone/v1/milestone_pb';
|
||||||
|
|
||||||
const reddark: string = COLORS[0][700];
|
const reddark: string = COLORS[0][700];
|
||||||
const redlight = COLORS[0][200];
|
const redlight = COLORS[0][200];
|
||||||
@@ -19,67 +20,66 @@ const purplelight = COLORS[12][200];
|
|||||||
const pinkdark: string = COLORS[15][700];
|
const pinkdark: string = COLORS[15][700];
|
||||||
const pinklight = COLORS[15][200];
|
const pinklight = COLORS[15][200];
|
||||||
|
|
||||||
export const ONBOARDING_EVENTS: OnboardingActions[] = [
|
const sthdark: string = COLORS[18][700];
|
||||||
|
const sthlight = COLORS[18][200];
|
||||||
|
|
||||||
|
export const ONBOARDING_MILESTONES: OnboardingActions[] = [
|
||||||
{
|
{
|
||||||
order: 0,
|
order: 0,
|
||||||
eventType: 'project.added',
|
milestoneType: MilestoneType.MILESTONE_TYPE_PROJECT_CREATED,
|
||||||
oneof: ['project.added'],
|
link: '/projects/create',
|
||||||
link: ['/projects/create'],
|
|
||||||
iconClasses: 'las la-database',
|
iconClasses: 'las la-database',
|
||||||
darkcolor: greendark,
|
darkcolor: greendark,
|
||||||
lightcolor: greenlight,
|
lightcolor: greenlight,
|
||||||
aggregateType: 'project',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
order: 1,
|
order: 1,
|
||||||
eventType: 'project.application.added',
|
milestoneType: MilestoneType.MILESTONE_TYPE_APPLICATION_CREATED,
|
||||||
oneof: ['project.application.added'],
|
link: '/projects/app-create',
|
||||||
link: ['/projects/app-create'],
|
|
||||||
iconClasses: 'lab la-openid',
|
iconClasses: 'lab la-openid',
|
||||||
darkcolor: purpledark,
|
darkcolor: purpledark,
|
||||||
lightcolor: purplelight,
|
lightcolor: purplelight,
|
||||||
aggregateType: 'project',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
order: 2,
|
|
||||||
eventType: 'user.human.added',
|
|
||||||
oneof: ['user.human.added'],
|
|
||||||
link: ['/users/create'],
|
|
||||||
iconClasses: 'las la-user',
|
|
||||||
darkcolor: bluedark,
|
|
||||||
lightcolor: bluelight,
|
|
||||||
aggregateType: 'user',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
order: 3,
|
order: 3,
|
||||||
eventType: 'user.grant.added',
|
milestoneType: MilestoneType.MILESTONE_TYPE_AUTHENTICATION_SUCCEEDED_ON_APPLICATION,
|
||||||
oneof: ['user.grant.added'],
|
link: 'https://zitadel.com/docs/guides/integrate/login-users',
|
||||||
link: ['/grant-create'],
|
iconClasses: 'las la-sign-in-alt',
|
||||||
|
darkcolor: sthdark,
|
||||||
|
lightcolor: sthlight,
|
||||||
|
} /*
|
||||||
|
{
|
||||||
|
order: 4,
|
||||||
|
milestoneType: 'user.human.added',
|
||||||
|
link: '/users/create',
|
||||||
|
iconClasses: 'las la-user',
|
||||||
|
darkcolor: bluedark,
|
||||||
|
lightcolor: bluelight,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
order: 5,
|
||||||
|
milestoneType: 'user.grant.added',
|
||||||
|
link: '/grant-create',
|
||||||
iconClasses: 'las la-shield-alt',
|
iconClasses: 'las la-shield-alt',
|
||||||
darkcolor: reddark,
|
darkcolor: reddark,
|
||||||
lightcolor: redlight,
|
lightcolor: redlight,
|
||||||
aggregateType: 'user_grant',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
order: 4,
|
order: 6,
|
||||||
eventType: 'instance.policy.label.added',
|
milestoneType: 'instance.policy.label.added',
|
||||||
oneof: ['instance.policy.label.added', 'instance.policy.label.changed'],
|
link: '/settings',
|
||||||
link: ['/settings'],
|
|
||||||
fragment: 'branding',
|
fragment: 'branding',
|
||||||
iconClasses: 'las la-swatchbook',
|
iconClasses: 'las la-swatchbook',
|
||||||
darkcolor: pinkdark,
|
darkcolor: pinkdark,
|
||||||
lightcolor: pinklight,
|
lightcolor: pinklight,
|
||||||
aggregateType: 'instance',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
order: 5,
|
order: 7,
|
||||||
eventType: 'instance.smtp.config.added',
|
milestoneType: 'instance.smtp.config.added',
|
||||||
oneof: ['instance.smtp.config.added', 'instance.smtp.config.changed'],
|
link: '/settings',
|
||||||
link: ['/settings'],
|
|
||||||
fragment: 'smtpprovider',
|
fragment: 'smtpprovider',
|
||||||
iconClasses: 'las la-envelope',
|
iconClasses: 'las la-envelope',
|
||||||
darkcolor: yellowdark,
|
darkcolor: yellowdark,
|
||||||
lightcolor: yellowlight,
|
lightcolor: yellowlight,
|
||||||
aggregateType: 'instance',
|
},*/,
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"TITLE": "Пуснете своя ZITADEL да работи",
|
"TITLE": "Пуснете своя ZITADEL да работи",
|
||||||
"DESCRIPTION": "Този контролен списък помага да настроите вашия екземпляр и ви насочва през най-важните стъпки"
|
"DESCRIPTION": "Този контролен списък помага да настроите вашия екземпляр и ви насочва през най-важните стъпки"
|
||||||
},
|
},
|
||||||
"EVENTS": {
|
"MILESTONES": {
|
||||||
"instance.policy.label.added": {
|
"instance.policy.label.added": {
|
||||||
"title": "Настройте марката си",
|
"title": "Настройте марката си",
|
||||||
"description": "Определете цвета и формата на вашето логин и качете вашето лого и икони.",
|
"description": "Определете цвета и формата на вашето логин и качете вашето лого и икони.",
|
||||||
@@ -62,15 +62,20 @@
|
|||||||
"description": "Задайте свои собствени настройки на пощенския сървър.",
|
"description": "Задайте свои собствени настройки на пощенския сървър.",
|
||||||
"action": "Настройка на SMTP"
|
"action": "Настройка на SMTP"
|
||||||
},
|
},
|
||||||
"project.added": {
|
"PROJECT_CREATED": {
|
||||||
"title": "Създайте проект",
|
"title": "Създайте проект",
|
||||||
"description": "Добавете проект и определете неговите роли и пълномощия.",
|
"description": "Добавете проект и определете неговите роли и пълномощия.",
|
||||||
"action": "Създайте проект"
|
"action": "Създайте проект"
|
||||||
},
|
},
|
||||||
"project.application.added": {
|
"APPLICATION_CREATED": {
|
||||||
"title": "Създайте приложение",
|
"title": "Регистрирайте приложението си",
|
||||||
"description": "Създайте уеб, естествено, api или saml приложение и настройте своя поток за удостоверяване.",
|
"description": "Регистрирайте вашето уеб, естествено, api или saml приложение и настройте поток за удостоверяване.",
|
||||||
"action": "Създаване на приложение"
|
"action": "Регистрирайте приложението"
|
||||||
|
},
|
||||||
|
"AUTHENTICATION_SUCCEEDED_ON_APPLICATION": {
|
||||||
|
"title": "Влезте в приложението си",
|
||||||
|
"description": "Интегрирайте приложението си с ZITADEL за удостоверяване и го тествайте, като влезете с администраторския си потребител.",
|
||||||
|
"action": "Влезте"
|
||||||
},
|
},
|
||||||
"user.human.added": {
|
"user.human.added": {
|
||||||
"title": "Добавете потребители",
|
"title": "Добавете потребители",
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"TITLE": "Bringe deine Instanz zum Laufen",
|
"TITLE": "Bringe deine Instanz zum Laufen",
|
||||||
"DESCRIPTION": "Diese Checkliste hilft bei der Einrichtung Ihrer Instanz und führt Sie durch die wichtigsten Schritte"
|
"DESCRIPTION": "Diese Checkliste hilft bei der Einrichtung Ihrer Instanz und führt Sie durch die wichtigsten Schritte"
|
||||||
},
|
},
|
||||||
"EVENTS": {
|
"MILESTONES": {
|
||||||
"instance.policy.label.added": {
|
"instance.policy.label.added": {
|
||||||
"title": "Branding anpassen",
|
"title": "Branding anpassen",
|
||||||
"description": "Definiere Farben und Form des Login-UIs und uploade deine Logos und Icons.",
|
"description": "Definiere Farben und Form des Login-UIs und uploade deine Logos und Icons.",
|
||||||
@@ -62,15 +62,20 @@
|
|||||||
"description": "Konfiguriere deinen Mailserver.",
|
"description": "Konfiguriere deinen Mailserver.",
|
||||||
"action": "SMTP einrichten"
|
"action": "SMTP einrichten"
|
||||||
},
|
},
|
||||||
"project.added": {
|
"PROJECT_CREATED": {
|
||||||
"title": "Erstelle ein Projekt",
|
"title": "Erstelle ein Projekt",
|
||||||
"description": "Erstelle dein erstes Projekt und definiere Rollen",
|
"description": "Erstelle dein erstes Projekt und definiere Rollen",
|
||||||
"action": "Projekt erstellen"
|
"action": "Projekt erstellen"
|
||||||
},
|
},
|
||||||
"project.application.added": {
|
"APPLICATION_CREATED": {
|
||||||
"title": "Erstelle eine App",
|
"title": "Registriere deine App",
|
||||||
"description": "Erstelle deine erste Web-, native, API oder SAML-applikation und konfiguriere den Authentification-flow.",
|
"description": "Registriere deine erste Web-, native, API oder SAML-Applikation und konfiguriere den Authentification-flow.",
|
||||||
"action": "App erstellen"
|
"action": "App registrieren"
|
||||||
|
},
|
||||||
|
"AUTHENTICATION_SUCCEEDED_ON_APPLICATION": {
|
||||||
|
"title": "Logge dich in deine App ein",
|
||||||
|
"description": "Integriere deine Applikation mit ZITADEL für die Authentifizierung und teste es, indem du dich mit deinem Admin-Benutzer einloggst.",
|
||||||
|
"action": "Einloggen"
|
||||||
},
|
},
|
||||||
"user.human.added": {
|
"user.human.added": {
|
||||||
"title": "Erfasse Benutzer",
|
"title": "Erfasse Benutzer",
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"TITLE": "Get your ZITADEL running",
|
"TITLE": "Get your ZITADEL running",
|
||||||
"DESCRIPTION": "This checklist helps to setup your instance and guides your through the most essential steps"
|
"DESCRIPTION": "This checklist helps to setup your instance and guides your through the most essential steps"
|
||||||
},
|
},
|
||||||
"EVENTS": {
|
"MILESTONES": {
|
||||||
"instance.policy.label.added": {
|
"instance.policy.label.added": {
|
||||||
"title": "Setup your brand",
|
"title": "Setup your brand",
|
||||||
"description": "Define coloring and shape of your login and upload your logo and icons.",
|
"description": "Define coloring and shape of your login and upload your logo and icons.",
|
||||||
@@ -62,15 +62,20 @@
|
|||||||
"description": "Set your own mail server settings.",
|
"description": "Set your own mail server settings.",
|
||||||
"action": "Setup SMTP"
|
"action": "Setup SMTP"
|
||||||
},
|
},
|
||||||
"project.added": {
|
"PROJECT_CREATED": {
|
||||||
"title": "Create a project",
|
"title": "Create a project",
|
||||||
"description": "Add a project and define its roles and authorizations.",
|
"description": "Add a project and define its roles and authorizations.",
|
||||||
"action": "Create project"
|
"action": "Create project"
|
||||||
},
|
},
|
||||||
"project.application.added": {
|
"APPLICATION_CREATED": {
|
||||||
"title": "Create an application",
|
"title": "Register your app",
|
||||||
"description": "Create a web, native, api or saml application and setup your authentication flow.",
|
"description": "Register your web, native, api or saml application and setup an authentication flow.",
|
||||||
"action": "Create app"
|
"action": "Register app"
|
||||||
|
},
|
||||||
|
"AUTHENTICATION_SUCCEEDED_ON_APPLICATION": {
|
||||||
|
"title": "Log in to your app",
|
||||||
|
"description": "Integrate your application with ZITADEL for authentication and test it by logging in with your admin user.",
|
||||||
|
"action": "Log in"
|
||||||
},
|
},
|
||||||
"user.human.added": {
|
"user.human.added": {
|
||||||
"title": "Add users",
|
"title": "Add users",
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"TITLE": "Ponte en marcha con ZITADEL",
|
"TITLE": "Ponte en marcha con ZITADEL",
|
||||||
"DESCRIPTION": "Esta lista de tareas te ayuda a configurar tu instancia y te guía por los pasos más esenciales"
|
"DESCRIPTION": "Esta lista de tareas te ayuda a configurar tu instancia y te guía por los pasos más esenciales"
|
||||||
},
|
},
|
||||||
"EVENTS": {
|
"MILESTONES": {
|
||||||
"instance.policy.label.added": {
|
"instance.policy.label.added": {
|
||||||
"title": "Configura tu imagen de marca",
|
"title": "Configura tu imagen de marca",
|
||||||
"description": "Define el esquema de colores, da forma a tu inicio de sesión y sube tu logo y tus iconos.",
|
"description": "Define el esquema de colores, da forma a tu inicio de sesión y sube tu logo y tus iconos.",
|
||||||
@@ -62,15 +62,20 @@
|
|||||||
"description": "Introduce la configuración de tu propio servidor de correo.",
|
"description": "Introduce la configuración de tu propio servidor de correo.",
|
||||||
"action": "Configurar SMTP"
|
"action": "Configurar SMTP"
|
||||||
},
|
},
|
||||||
"project.added": {
|
"PROJECT_CREATED": {
|
||||||
"title": "Crea tu primer proyecto",
|
"title": "Crea tu primer proyecto",
|
||||||
"description": "Añade tu primer proyecto y define sus roles y autorizaciones.",
|
"description": "Añade tu primer proyecto y define sus roles y autorizaciones.",
|
||||||
"action": "Crear proyecto"
|
"action": "Crear proyecto"
|
||||||
},
|
},
|
||||||
"project.application.added": {
|
"APPLICATION_CREATED": {
|
||||||
"title": "Crea tu primera aplicación",
|
"title": "Registra tu aplicación",
|
||||||
"description": "Crea una aplicación web, nativa, api o saml y configura tu flujo de autenticación.",
|
"description": "Registra tu aplicación web, nativa, api o saml y configura tu flujo de autenticación.",
|
||||||
"action": "Crear app"
|
"action": "Registrar app"
|
||||||
|
},
|
||||||
|
"AUTHENTICATION_SUCCEEDED_ON_APPLICATION": {
|
||||||
|
"title": "Inicia sesión en tu aplicación",
|
||||||
|
"description": "Integra tu aplicación con ZITADEL para la autenticación y pruébala iniciando sesión con tu usuario administrador.",
|
||||||
|
"action": "Iniciar sesión"
|
||||||
},
|
},
|
||||||
"user.human.added": {
|
"user.human.added": {
|
||||||
"title": "Añade usuarios",
|
"title": "Añade usuarios",
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"TITLE": "Faites fonctionner votre ZITADEL",
|
"TITLE": "Faites fonctionner votre ZITADEL",
|
||||||
"DESCRIPTION": "Cette liste de contrôle vous aide à configurer votre instance et vous guide à travers les étapes les plus essentielles."
|
"DESCRIPTION": "Cette liste de contrôle vous aide à configurer votre instance et vous guide à travers les étapes les plus essentielles."
|
||||||
},
|
},
|
||||||
"EVENTS": {
|
"MILESTONES": {
|
||||||
"instance.policy.label.added": {
|
"instance.policy.label.added": {
|
||||||
"title": "Créez votre marque",
|
"title": "Créez votre marque",
|
||||||
"description": "Définissez la couleur et la forme de votre connexion et téléchargez votre logo et vos icônes.",
|
"description": "Définissez la couleur et la forme de votre connexion et téléchargez votre logo et vos icônes.",
|
||||||
@@ -62,15 +62,20 @@
|
|||||||
"description": "Définissez paramètres de serveur de messagerie",
|
"description": "Définissez paramètres de serveur de messagerie",
|
||||||
"action": "Configurez"
|
"action": "Configurez"
|
||||||
},
|
},
|
||||||
"project.added": {
|
"PROJECT_CREATED": {
|
||||||
"title": "Créez projet",
|
"title": "Créez projet",
|
||||||
"description": "Ajoutez projet et définissez ses rôles et autorisations.",
|
"description": "Ajoutez projet et définissez ses rôles et autorisations.",
|
||||||
"action": "Créez projet"
|
"action": "Créez projet"
|
||||||
},
|
},
|
||||||
"project.application.added": {
|
"APPLICATION_CREATED": {
|
||||||
"title": "Créez votre première application",
|
"title": "Enregistrez votre application",
|
||||||
"description": "Créez une application web, native, api ou saml et configurez votre flux d'authentification.",
|
"description": "Enregistrez votre application web, native, api ou saml et configurez un flux d'authentification.",
|
||||||
"action": "Créez application"
|
"action": "Enregistrez l'application"
|
||||||
|
},
|
||||||
|
"AUTHENTICATION_SUCCEEDED_ON_APPLICATION": {
|
||||||
|
"title": "Connectez-vous à votre application",
|
||||||
|
"description": "Intégrez votre application avec ZITADEL pour l'authentification et testez-la en vous connectant avec votre utilisateur administrateur.",
|
||||||
|
"action": "Connexion"
|
||||||
},
|
},
|
||||||
"user.human.added": {
|
"user.human.added": {
|
||||||
"title": "Ajouter des utilisateurs",
|
"title": "Ajouter des utilisateurs",
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"TITLE": "Fate funzionare il vostro ZITADEL",
|
"TITLE": "Fate funzionare il vostro ZITADEL",
|
||||||
"DESCRIPTION": "Questa lista di azioni aiuta a configurare la vostra istanza e vi guida attraverso i passaggi più essenziali."
|
"DESCRIPTION": "Questa lista di azioni aiuta a configurare la vostra istanza e vi guida attraverso i passaggi più essenziali."
|
||||||
},
|
},
|
||||||
"EVENTS": {
|
"MILESTONES": {
|
||||||
"instance.policy.label.added": {
|
"instance.policy.label.added": {
|
||||||
"title": "Imposta il tuo marchio",
|
"title": "Imposta il tuo marchio",
|
||||||
"description": "Definisci la colorazione e il design del vostro login e caricate il vostro logo e le vostre icone.",
|
"description": "Definisci la colorazione e il design del vostro login e caricate il vostro logo e le vostre icone.",
|
||||||
@@ -62,15 +62,20 @@
|
|||||||
"description": "Imposta il proprio server di posta",
|
"description": "Imposta il proprio server di posta",
|
||||||
"action": "Configura SMTP"
|
"action": "Configura SMTP"
|
||||||
},
|
},
|
||||||
"project.added": {
|
"PROJECT_CREATED": {
|
||||||
"title": "Crea il tuo primo progetto",
|
"title": "Crea il tuo primo progetto",
|
||||||
"description": "Aggiungere il primo progetto e definire i ruoli e le autorizzazioni.",
|
"description": "Aggiungere il primo progetto e definire i ruoli e le autorizzazioni.",
|
||||||
"action": "Crea progetto"
|
"action": "Crea progetto"
|
||||||
},
|
},
|
||||||
"project.application.added": {
|
"APPLICATION_CREATED": {
|
||||||
"title": "Crea la tua prima applicazione",
|
"title": "Registra la tua app",
|
||||||
"description": "Crea un'applicazione web, nativa, api o saml e imposta il flusso di autenticazione.",
|
"description": "Registra la tua applicazione web, nativa, api o saml e configura un flusso di autenticazione.",
|
||||||
"action": "Crea applicazione"
|
"action": "Registra app"
|
||||||
|
},
|
||||||
|
"AUTHENTICATION_SUCCEEDED_ON_APPLICATION": {
|
||||||
|
"title": "Accedi alla tua app",
|
||||||
|
"description": "Integra la tua applicazione con ZITADEL per l'autenticazione e testala accedendo con il tuo utente amministratore.",
|
||||||
|
"action": "Accedi"
|
||||||
},
|
},
|
||||||
"user.human.added": {
|
"user.human.added": {
|
||||||
"title": "Aggiungi utenti",
|
"title": "Aggiungi utenti",
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"TITLE": "ZITADELの起動",
|
"TITLE": "ZITADELの起動",
|
||||||
"DESCRIPTION": "このチェックリストを使用して、重要な手順を確認しながらインスタンスをセットアップします。"
|
"DESCRIPTION": "このチェックリストを使用して、重要な手順を確認しながらインスタンスをセットアップします。"
|
||||||
},
|
},
|
||||||
"EVENTS": {
|
"MILESTONES": {
|
||||||
"instance.policy.label.added": {
|
"instance.policy.label.added": {
|
||||||
"title": "ブランドをセットアップする",
|
"title": "ブランドをセットアップする",
|
||||||
"description": "ログインの色と形状を定義し、ロゴとアイコンをアップロードします。",
|
"description": "ログインの色と形状を定義し、ロゴとアイコンをアップロードします。",
|
||||||
@@ -62,15 +62,20 @@
|
|||||||
"description": "独自のメールサーバーを設定します。",
|
"description": "独自のメールサーバーを設定します。",
|
||||||
"action": "SMTP 設定を設定する"
|
"action": "SMTP 設定を設定する"
|
||||||
},
|
},
|
||||||
"project.added": {
|
"PROJECT_CREATED": {
|
||||||
"title": "最初のプロジェクトを作成する",
|
"title": "最初のプロジェクトを作成する",
|
||||||
"description": "最初のプロジェクトを追加し、ロールと認証を定義します。",
|
"description": "最初のプロジェクトを追加し、ロールと認証を定義します。",
|
||||||
"action": "プロジェクトを作成"
|
"action": "プロジェクトを作成"
|
||||||
},
|
},
|
||||||
"project.application.added": {
|
"APPLICATION_CREATED": {
|
||||||
"title": "最初のアプリケーションを作成する",
|
"title": "アプリを登録する",
|
||||||
"description": "Web、ネイティブ、API、またはSAMLアプリケーションを作成し、認証フローをセットアップします。",
|
"description": "Web、ネイティブ、API、またはSAMLアプリケーションを登録し、認証フローをセットアップします。",
|
||||||
"action": "アプリケーションを作成"
|
"action": "アプリを登録する"
|
||||||
|
},
|
||||||
|
"AUTHENTICATION_SUCCEEDED_ON_APPLICATION": {
|
||||||
|
"title": "アプリにログインする",
|
||||||
|
"description": "アプリケーションをZITADELと統合して認証し、管理者ユーザーでログインしてテストします。",
|
||||||
|
"action": "ログイン"
|
||||||
},
|
},
|
||||||
"user.human.added": {
|
"user.human.added": {
|
||||||
"title": "ユーザーを追加する",
|
"title": "ユーザーを追加する",
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"TITLE": "Почнете со ZITADEL",
|
"TITLE": "Почнете со ZITADEL",
|
||||||
"DESCRIPTION": "Оваа листа со чекори помага при подесувањето на вашата инстанца и ве води низ најважните чекори"
|
"DESCRIPTION": "Оваа листа со чекори помага при подесувањето на вашата инстанца и ве води низ најважните чекори"
|
||||||
},
|
},
|
||||||
"EVENTS": {
|
"MILESTONES": {
|
||||||
"instance.policy.label.added": {
|
"instance.policy.label.added": {
|
||||||
"title": "Подесете го вашиот бренд",
|
"title": "Подесете го вашиот бренд",
|
||||||
"description": "Дефинирајте боја и форма за вашиот процез за најава и прикачете ги вашите лого и икони.",
|
"description": "Дефинирајте боја и форма за вашиот процез за најава и прикачете ги вашите лого и икони.",
|
||||||
@@ -62,15 +62,20 @@
|
|||||||
"description": "Подесете го вашиот сервер за е-пошта.",
|
"description": "Подесете го вашиот сервер за е-пошта.",
|
||||||
"action": "Подеси SMTP"
|
"action": "Подеси SMTP"
|
||||||
},
|
},
|
||||||
"project.added": {
|
"PROJECT_CREATED": {
|
||||||
"title": "Креирајте проект",
|
"title": "Креирајте проект",
|
||||||
"description": "Додадете проект и дефинирајте ги неговите улоги и овластувања.",
|
"description": "Додадете проект и дефинирајте ги неговите улоги и овластувања.",
|
||||||
"action": "Креирај проект"
|
"action": "Креирај проект"
|
||||||
},
|
},
|
||||||
"project.application.added": {
|
"APPLICATION_CREATED": {
|
||||||
"title": "Креирајте апликација",
|
"title": "Регистрирајте ја вашата апликација",
|
||||||
"description": "Креирајте веб, нативна, API или SAML апликација и подесете го вашите автентикациски правила.",
|
"description": "Регистрирајте ја вашата веб, нативна, API или SAML апликација и подесете ја автентикацијата.",
|
||||||
"action": "Креирај апликација"
|
"action": "Регистрирај апликација"
|
||||||
|
},
|
||||||
|
"AUTHENTICATION_SUCCEEDED_ON_APPLICATION": {
|
||||||
|
"title": "Најавете се во вашата апликација",
|
||||||
|
"description": "Интегрирајте ја вашата апликација со ZITADEL за автентикација и тестирајте ја со најавување со вашиот администраторски корисник.",
|
||||||
|
"action": "Најави се"
|
||||||
},
|
},
|
||||||
"user.human.added": {
|
"user.human.added": {
|
||||||
"title": "Додадете корисници",
|
"title": "Додадете корисници",
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"TITLE": "Uruchom swój ZITADEL",
|
"TITLE": "Uruchom swój ZITADEL",
|
||||||
"DESCRIPTION": "Ta lista kontrolna pomoże Ci skonfigurować instancję i poprowadzi Cię przez najważniejsze kroki."
|
"DESCRIPTION": "Ta lista kontrolna pomoże Ci skonfigurować instancję i poprowadzi Cię przez najważniejsze kroki."
|
||||||
},
|
},
|
||||||
"EVENTS": {
|
"MILESTONES": {
|
||||||
"instance.policy.label.added": {
|
"instance.policy.label.added": {
|
||||||
"title": "Skonfiguruj swoją markę",
|
"title": "Skonfiguruj swoją markę",
|
||||||
"description": "Zdefiniuj kolorystykę i kształt swojego loginu oraz wgraj swoje logo i ikony.",
|
"description": "Zdefiniuj kolorystykę i kształt swojego loginu oraz wgraj swoje logo i ikony.",
|
||||||
@@ -62,15 +62,20 @@
|
|||||||
"description": "Ustawienie własnego serwera pocztowego",
|
"description": "Ustawienie własnego serwera pocztowego",
|
||||||
"action": "skonfiguruj ustawienia SMTP"
|
"action": "skonfiguruj ustawienia SMTP"
|
||||||
},
|
},
|
||||||
"project.added": {
|
"PROJECT_CREATED": {
|
||||||
"title": "Stwórz swój pierwszy projekt",
|
"title": "Stwórz swój pierwszy projekt",
|
||||||
"description": "Dodaj swój pierwszy projekt i określ jego role i uprawnienia.",
|
"description": "Dodaj swój pierwszy projekt i określ jego role i uprawnienia.",
|
||||||
"action": "Utwórz projekt"
|
"action": "Utwórz projekt"
|
||||||
},
|
},
|
||||||
"project.application.added": {
|
"APPLICATION_CREATED": {
|
||||||
"title": "Utwórz swoją pierwszą aplikację",
|
"title": "Zarejestruj swoją aplikację",
|
||||||
"description": "Utwórz aplikację internetową, natywną, api lub saml i skonfiguruj swój przepływ uwierzytelniania.",
|
"description": "Zarejestruj swoją aplikację webową, natywną, API lub SAML i skonfiguruj przepływ uwierzytelniania.",
|
||||||
"action": "Utwórz aplikację"
|
"action": "Zarejestruj aplikację"
|
||||||
|
},
|
||||||
|
"AUTHENTICATION_SUCCEEDED_ON_APPLICATION": {
|
||||||
|
"title": "Zaloguj się do swojej aplikacji",
|
||||||
|
"description": "Zintegruj swoją aplikację z ZITADEL w celu uwierzytelniania i przetestuj ją, logując się za pomocą swojego użytkownika administratora.",
|
||||||
|
"action": "Zaloguj się"
|
||||||
},
|
},
|
||||||
"user.human.added": {
|
"user.human.added": {
|
||||||
"title": "Dodaj użytkowników",
|
"title": "Dodaj użytkowników",
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"TITLE": "Inicie o ZITADEL",
|
"TITLE": "Inicie o ZITADEL",
|
||||||
"DESCRIPTION": "Esta lista de verificação ajuda a configurar sua instância e orienta você nas etapas mais essenciais"
|
"DESCRIPTION": "Esta lista de verificação ajuda a configurar sua instância e orienta você nas etapas mais essenciais"
|
||||||
},
|
},
|
||||||
"EVENTS": {
|
"MILESTONES": {
|
||||||
"instance.policy.label.added": {
|
"instance.policy.label.added": {
|
||||||
"title": "Configure sua marca",
|
"title": "Configure sua marca",
|
||||||
"description": "Defina cores e forma para o seu login e faça o upload do seu logotipo e ícones.",
|
"description": "Defina cores e forma para o seu login e faça o upload do seu logotipo e ícones.",
|
||||||
@@ -62,15 +62,20 @@
|
|||||||
"description": "Configure as configurações do seu próprio servidor de e-mail.",
|
"description": "Configure as configurações do seu próprio servidor de e-mail.",
|
||||||
"action": "Configurar SMTP"
|
"action": "Configurar SMTP"
|
||||||
},
|
},
|
||||||
"project.added": {
|
"PROJECT_CREATED": {
|
||||||
"title": "Crie um projeto",
|
"title": "Crie um projeto",
|
||||||
"description": "Adicione um projeto e defina suas funções e autorizações.",
|
"description": "Adicione um projeto e defina suas funções e autorizações.",
|
||||||
"action": "Criar projeto"
|
"action": "Criar projeto"
|
||||||
},
|
},
|
||||||
"project.application.added": {
|
"APPLICATION_CREATED": {
|
||||||
"title": "Crie um aplicativo",
|
"title": "Registre seu aplicativo",
|
||||||
"description": "Crie um aplicativo da web, nativo, API ou SAML e configure o fluxo de autenticação.",
|
"description": "Registre seu aplicativo web, nativo, api ou saml e configure um fluxo de autenticação.",
|
||||||
"action": "Criar aplicativo"
|
"action": "Registrar aplicativo"
|
||||||
|
},
|
||||||
|
"AUTHENTICATION_SUCCEEDED_ON_APPLICATION": {
|
||||||
|
"title": "Faça login no seu aplicativo",
|
||||||
|
"description": "Integre seu aplicativo com o ZITADEL para autenticação e teste-o fazendo login com seu usuário administrador.",
|
||||||
|
"action": "Faça login"
|
||||||
},
|
},
|
||||||
"user.human.added": {
|
"user.human.added": {
|
||||||
"title": "Adicione usuários",
|
"title": "Adicione usuários",
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"TITLE": "让你的ZITADEL运转起来",
|
"TITLE": "让你的ZITADEL运转起来",
|
||||||
"DESCRIPTION": "这份清单有助于设置你的实例,并指导你完成最重要的步骤"
|
"DESCRIPTION": "这份清单有助于设置你的实例,并指导你完成最重要的步骤"
|
||||||
},
|
},
|
||||||
"EVENTS": {
|
"MILESTONES": {
|
||||||
"instance.policy.label.added": {
|
"instance.policy.label.added": {
|
||||||
"title": "设置你的品牌",
|
"title": "设置你的品牌",
|
||||||
"description": "定义你的登录的颜色和形状,上传你的标志和图标。",
|
"description": "定义你的登录的颜色和形状,上传你的标志和图标。",
|
||||||
@@ -62,16 +62,21 @@
|
|||||||
"description": "设置你自己的邮件服务器设置",
|
"description": "设置你自己的邮件服务器设置",
|
||||||
"action": "设置 SMTP 设置"
|
"action": "设置 SMTP 设置"
|
||||||
},
|
},
|
||||||
"project.added": {
|
"PROJECT_CREATED": {
|
||||||
"title": "创建你的第一个项目",
|
"title": "创建你的第一个项目",
|
||||||
"description": "添加你的第一个项目并定义其角色和授权。",
|
"description": "添加你的第一个项目并定义其角色和授权。",
|
||||||
"action": "创建项目"
|
"action": "创建项目"
|
||||||
},
|
},
|
||||||
"project.application.added": {
|
"APPLICATION_CREATED": {
|
||||||
"title": "创建你的第一个应用程序",
|
"title": "注册你的应用程序",
|
||||||
"description": "创建一个web、native、api或saml应用程序并设置你的认证流程。",
|
"description": "创建一个web、native、api或saml应用程序并设置你的认证流程。",
|
||||||
"action": "创建应用程序"
|
"action": "创建应用程序"
|
||||||
},
|
},
|
||||||
|
"AUTHENTICATION_SUCCEEDED_ON_APPLICATION": {
|
||||||
|
"title": "登录你的应用程序",
|
||||||
|
"description": "将你的应用程序与 ZITADEL 集成以进行身份验证,并通过使用管理员用户登录来测试它。",
|
||||||
|
"action": "登录"
|
||||||
|
},
|
||||||
"user.human.added": {
|
"user.human.added": {
|
||||||
"title": "添加用户",
|
"title": "添加用户",
|
||||||
"description": "添加你的应用程序用户",
|
"description": "添加你的应用程序用户",
|
||||||
|
24
internal/api/grpc/admin/milestone.go
Normal file
24
internal/api/grpc/admin/milestone.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
|
object_pb "github.com/zitadel/zitadel/internal/api/grpc/object"
|
||||||
|
"github.com/zitadel/zitadel/pkg/grpc/admin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Server) ListMilestones(ctx context.Context, req *admin.ListMilestonesRequest) (*admin.ListMilestonesResponse, error) {
|
||||||
|
queries, err := listMilestonesToModel(authz.GetInstance(ctx).InstanceID(), req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := s.query.SearchMilestones(ctx, []string{authz.GetInstance(ctx).InstanceID()}, queries)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &admin.ListMilestonesResponse{
|
||||||
|
Result: milestoneViewsToPb(resp.Milestones),
|
||||||
|
Details: object_pb.ToListDetails(resp.Count, resp.Sequence, resp.LastRun),
|
||||||
|
}, nil
|
||||||
|
}
|
99
internal/api/grpc/admin/milestone_converter.go
Normal file
99
internal/api/grpc/admin/milestone_converter.go
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/zitadel/zitadel/internal/api/grpc/object"
|
||||||
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
|
"github.com/zitadel/zitadel/internal/query"
|
||||||
|
"github.com/zitadel/zitadel/internal/repository/milestone"
|
||||||
|
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
|
||||||
|
milestone_pb "github.com/zitadel/zitadel/pkg/grpc/milestone"
|
||||||
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
)
|
||||||
|
|
||||||
|
func listMilestonesToModel(instanceID string, req *admin_pb.ListMilestonesRequest) (*query.MilestonesSearchQueries, error) {
|
||||||
|
offset, limit, asc := object.ListQueryToModel(req.Query)
|
||||||
|
queries, err := milestoneQueriesToModel(req.GetQueries())
|
||||||
|
instanceIDQuery, err := query.NewTextQuery(query.MilestoneInstanceIDColID, instanceID, query.TextEquals)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
queries = append(queries, instanceIDQuery)
|
||||||
|
return &query.MilestonesSearchQueries{
|
||||||
|
SearchRequest: query.SearchRequest{
|
||||||
|
Offset: offset,
|
||||||
|
Limit: limit,
|
||||||
|
Asc: asc,
|
||||||
|
SortingColumn: milestoneFieldNameToSortingColumn(req.SortingColumn),
|
||||||
|
},
|
||||||
|
Queries: queries,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func milestoneQueriesToModel(queries []*milestone_pb.MilestoneQuery) (q []query.SearchQuery, err error) {
|
||||||
|
q = make([]query.SearchQuery, len(queries))
|
||||||
|
for i, query := range queries {
|
||||||
|
q[i], err = milestoneQueryToModel(query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return q, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func milestoneQueryToModel(milestoneQuery *milestone_pb.MilestoneQuery) (query.SearchQuery, error) {
|
||||||
|
switch q := milestoneQuery.Query.(type) {
|
||||||
|
case *milestone_pb.MilestoneQuery_IsReachedQuery:
|
||||||
|
if q.IsReachedQuery.GetReached() {
|
||||||
|
return query.NewNotNullQuery(query.MilestoneReachedDateColID)
|
||||||
|
}
|
||||||
|
return query.NewIsNullQuery(query.MilestoneReachedDateColID)
|
||||||
|
default:
|
||||||
|
return nil, errors.ThrowInvalidArgument(nil, "ADMIN-sE7pc", "List.Query.Invalid")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func milestoneFieldNameToSortingColumn(field milestone_pb.MilestoneFieldName) query.Column {
|
||||||
|
switch field {
|
||||||
|
case milestone_pb.MilestoneFieldName_MILESTONE_FIELD_NAME_REACHED_DATE:
|
||||||
|
return query.MilestoneReachedDateColID
|
||||||
|
default:
|
||||||
|
return query.MilestoneTypeColID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func milestoneViewsToPb(milestones []*query.Milestone) []*milestone_pb.Milestone {
|
||||||
|
resp := make([]*milestone_pb.Milestone, len(milestones))
|
||||||
|
for i, idp := range milestones {
|
||||||
|
resp[i] = modelMilestoneViewToPb(idp)
|
||||||
|
}
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
func modelMilestoneViewToPb(m *query.Milestone) *milestone_pb.Milestone {
|
||||||
|
mspb := &milestone_pb.Milestone{
|
||||||
|
Type: modelMilestoneTypeToPb(m.Type),
|
||||||
|
}
|
||||||
|
if !m.ReachedDate.IsZero() {
|
||||||
|
mspb.ReachedDate = timestamppb.New(m.ReachedDate)
|
||||||
|
}
|
||||||
|
return mspb
|
||||||
|
}
|
||||||
|
|
||||||
|
func modelMilestoneTypeToPb(t milestone.Type) milestone_pb.MilestoneType {
|
||||||
|
switch t {
|
||||||
|
case milestone.InstanceCreated:
|
||||||
|
return milestone_pb.MilestoneType_MILESTONE_TYPE_INSTANCE_CREATED
|
||||||
|
case milestone.AuthenticationSucceededOnInstance:
|
||||||
|
return milestone_pb.MilestoneType_MILESTONE_TYPE_AUTHENTICATION_SUCCEEDED_ON_INSTANCE
|
||||||
|
case milestone.ProjectCreated:
|
||||||
|
return milestone_pb.MilestoneType_MILESTONE_TYPE_PROJECT_CREATED
|
||||||
|
case milestone.ApplicationCreated:
|
||||||
|
return milestone_pb.MilestoneType_MILESTONE_TYPE_APPLICATION_CREATED
|
||||||
|
case milestone.AuthenticationSucceededOnApplication:
|
||||||
|
return milestone_pb.MilestoneType_MILESTONE_TYPE_AUTHENTICATION_SUCCEEDED_ON_APPLICATION
|
||||||
|
case milestone.InstanceDeleted:
|
||||||
|
return milestone_pb.MilestoneType_MILESTONE_TYPE_INSTANCE_DELETED
|
||||||
|
default:
|
||||||
|
return milestone_pb.MilestoneType_MILESTONE_TYPE_UNSPECIFIED
|
||||||
|
}
|
||||||
|
}
|
@@ -14,6 +14,7 @@ import "zitadel/event.proto";
|
|||||||
import "zitadel/management.proto";
|
import "zitadel/management.proto";
|
||||||
import "zitadel/v1.proto";
|
import "zitadel/v1.proto";
|
||||||
import "zitadel/message.proto";
|
import "zitadel/message.proto";
|
||||||
|
import "zitadel/milestone/v1/milestone.proto";
|
||||||
|
|
||||||
import "google/api/annotations.proto";
|
import "google/api/annotations.proto";
|
||||||
import "google/api/field_behavior.proto";
|
import "google/api/field_behavior.proto";
|
||||||
@@ -3773,6 +3774,23 @@ service AdminService {
|
|||||||
permission: "iam.feature.write";
|
permission: "iam.feature.write";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc ListMilestones(ListMilestonesRequest) returns (ListMilestonesResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
post: "/milestones/_search";
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
|
||||||
|
option (zitadel.v1.auth_option) = {
|
||||||
|
permission: "milestones.read";
|
||||||
|
};
|
||||||
|
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
tags: "Milestones";
|
||||||
|
summary: "Search Milestones";
|
||||||
|
description: "Returns a list of reached instance usage milestones."
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -7893,3 +7911,17 @@ message ActivateFeatureLoginDefaultOrgRequest {}
|
|||||||
message ActivateFeatureLoginDefaultOrgResponse {
|
message ActivateFeatureLoginDefaultOrgResponse {
|
||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message ListMilestonesRequest {
|
||||||
|
//list limitations and ordering
|
||||||
|
zitadel.v1.ListQuery query = 1;
|
||||||
|
// the field the result is sorted
|
||||||
|
zitadel.milestone.v1.MilestoneFieldName sorting_column = 2;
|
||||||
|
//criteria the client is looking for
|
||||||
|
repeated zitadel.milestone.v1.MilestoneQuery queries = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListMilestonesResponse {
|
||||||
|
zitadel.v1.ListDetails details = 1;
|
||||||
|
repeated zitadel.milestone.v1.Milestone result = 2;
|
||||||
|
}
|
||||||
|
49
proto/zitadel/milestone/v1/milestone.proto
Normal file
49
proto/zitadel/milestone/v1/milestone.proto
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
import "zitadel/object.proto";
|
||||||
|
import "validate/validate.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||||
|
|
||||||
|
package zitadel.milestone.v1;
|
||||||
|
|
||||||
|
option go_package ="github.com/zitadel/zitadel/pkg/grpc/milestone";
|
||||||
|
|
||||||
|
enum MilestoneType {
|
||||||
|
MILESTONE_TYPE_UNSPECIFIED = 0;
|
||||||
|
MILESTONE_TYPE_INSTANCE_CREATED = 1;
|
||||||
|
MILESTONE_TYPE_AUTHENTICATION_SUCCEEDED_ON_INSTANCE = 2;
|
||||||
|
MILESTONE_TYPE_PROJECT_CREATED = 3;
|
||||||
|
MILESTONE_TYPE_APPLICATION_CREATED = 4;
|
||||||
|
MILESTONE_TYPE_AUTHENTICATION_SUCCEEDED_ON_APPLICATION = 5;
|
||||||
|
MILESTONE_TYPE_INSTANCE_DELETED = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MilestoneFieldName {
|
||||||
|
MILESTONE_FIELD_NAME_UNSPECIFIED = 0;
|
||||||
|
MILESTONE_FIELD_NAME_TYPE = 1;
|
||||||
|
MILESTONE_FIELD_NAME_REACHED_DATE = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Milestone {
|
||||||
|
// For the milestones, the standard details are not projected yet
|
||||||
|
reserved 1;
|
||||||
|
reserved "details";
|
||||||
|
MilestoneType type = 2;
|
||||||
|
google.protobuf.Timestamp reached_date = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MilestoneQuery {
|
||||||
|
oneof query {
|
||||||
|
IsReachedQuery is_reached_query = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message IsReachedQuery {
|
||||||
|
bool reached = 1 [
|
||||||
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
description: "only reached milestones";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
Reference in New Issue
Block a user