mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:47:32 +00:00
feat(console): split granted from owned project modules, general ui ux fixes (#286)
* add iam label, user avatar * avatar component * split granted and owned modules * move components to resp module * refactor project contributors, g project nav * rem console logs, add avatar for org members * fix changes loading, auth user page * refactor home, i18n * fix changes side overflow * lint
This commit is contained in:
@@ -32,7 +32,12 @@
|
|||||||
"styles": [
|
"styles": [
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": [],
|
||||||
|
"allowedCommonJsDependencies": [
|
||||||
|
"@angular/common/locales/de",
|
||||||
|
"src/app/proto/generated/*.js",
|
||||||
|
"src/app/proto/generated/**/*.js"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
|
@@ -10,9 +10,17 @@ const routes: Routes = [
|
|||||||
loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule),
|
loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule),
|
||||||
canActivate: [AuthGuard],
|
canActivate: [AuthGuard],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'granted-projects',
|
||||||
|
loadChildren: () => import('./pages/granted-projects/granted-projects.module').then(m => m.GrantedProjectsModule),
|
||||||
|
canActivate: [AuthGuard, RoleGuard],
|
||||||
|
data: {
|
||||||
|
roles: ['project.read'],
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'projects',
|
path: 'projects',
|
||||||
loadChildren: () => import('./pages/projects/projects.module').then(m => m.ProjectsModule),
|
loadChildren: () => import('./pages/owned-projects/owned-projects.module').then(m => m.OwnedProjectsModule),
|
||||||
canActivate: [AuthGuard, RoleGuard],
|
canActivate: [AuthGuard, RoleGuard],
|
||||||
data: {
|
data: {
|
||||||
roles: ['project.read'],
|
roles: ['project.read'],
|
||||||
|
@@ -1,110 +1,116 @@
|
|||||||
<mat-toolbar class="root-header">
|
<ng-container *ngIf="(authService.user | async) || {} as user">
|
||||||
<button aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
|
<mat-toolbar class="root-header">
|
||||||
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
|
<button aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
|
||||||
</button>
|
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
|
||||||
<a *ngIf="(isHandset$ | async) == false" class="title ailerons" [routerLink]="['/']">
|
</button>
|
||||||
<img class="logo" *ngIf="componentCssClass == 'dark-theme'; else lighttheme"
|
<a *ngIf="(isHandset$ | async) == false" class="title ailerons" [routerLink]="['/']">
|
||||||
src="../assets/images/zitadel-logo-oneline-darkdesign.svg" />
|
<img class="logo" *ngIf="componentCssClass == 'dark-theme'; else lighttheme"
|
||||||
<ng-template #lighttheme>
|
src="../assets/images/zitadel-logo-oneline-darkdesign.svg" />
|
||||||
<img class="logo" src="../assets/images/zitadel-logo-oneline-lightdesign.svg" />
|
<ng-template #lighttheme>
|
||||||
</ng-template>
|
<img class="logo" src="../assets/images/zitadel-logo-oneline-lightdesign.svg" />
|
||||||
</a>
|
</ng-template>
|
||||||
|
</a>
|
||||||
|
|
||||||
<button (click)="loadOrgs()" *ngIf="profile?.id && org" mat-button
|
<button (click)="loadOrgs()" *ngIf="profile?.id && org" mat-button
|
||||||
[matMenuTriggerFor]="menu">{{org?.name ? org.name : 'NO NAME'}}
|
[matMenuTriggerFor]="menu">{{org?.name ? org.name : 'NO NAME'}}
|
||||||
<mat-icon>
|
<mat-icon>
|
||||||
arrow_drop_down</mat-icon>
|
arrow_drop_down</mat-icon>
|
||||||
</button>
|
|
||||||
|
|
||||||
<mat-menu #menu="matMenu">
|
|
||||||
<mat-progress-bar *ngIf="orgLoading" color="accent" mode="indeterminate"></mat-progress-bar>
|
|
||||||
<button class="show-all" mat-menu-item [routerLink]="[ '/org/overview' ]">Show all organizations</button>
|
|
||||||
|
|
||||||
<button [ngClass]="{'active': temporg.id === org?.id}" [disabled]="!temporg.id" *ngFor="let temporg of orgs"
|
|
||||||
mat-menu-item (click)="setActiveOrg(temporg)">
|
|
||||||
<mat-icon class="avatar">business</mat-icon>
|
|
||||||
{{temporg?.name ? temporg.name : 'NO NAME'}}
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<ng-template appHasRole [appHasRole]="['iam.write']">
|
<mat-menu #menu="matMenu">
|
||||||
<button mat-menu-item [routerLink]="[ '/org/create' ]">
|
<mat-progress-bar *ngIf="orgLoading" color="accent" mode="indeterminate"></mat-progress-bar>
|
||||||
<mat-icon class="avatar">add</mat-icon>
|
<button class="show-all" mat-menu-item [routerLink]="[ '/org/overview' ]">Show all organizations</button>
|
||||||
{{'MENU.NEWORG' | translate}}
|
|
||||||
|
<button [ngClass]="{'active': temporg.id === org?.id}" [disabled]="!temporg.id" *ngFor="let temporg of orgs"
|
||||||
|
mat-menu-item (click)="setActiveOrg(temporg)">
|
||||||
|
<mat-icon class="avatar">business</mat-icon>
|
||||||
|
{{temporg?.name ? temporg.name : 'NO NAME'}}
|
||||||
</button>
|
</button>
|
||||||
</ng-template>
|
|
||||||
</mat-menu>
|
|
||||||
<span class="fill-space"></span>
|
|
||||||
|
|
||||||
<ng-template appHasRole [appHasRole]="['iam.write']">
|
<ng-template appHasRole [appHasRole]="['iam.write']">
|
||||||
<div matTooltip="IAM Administrator" class="iamreadwrite"></div>
|
<button mat-menu-item [routerLink]="[ '/org/create' ]">
|
||||||
</ng-template>
|
<mat-icon class="avatar">add</mat-icon>
|
||||||
|
{{'MENU.NEWORG' | translate}}
|
||||||
|
</button>
|
||||||
|
</ng-template>
|
||||||
|
</mat-menu>
|
||||||
|
<span class="fill-space"></span>
|
||||||
|
|
||||||
<div (clickOutside)="closeAccountCard()" class="icon-container">
|
<div (clickOutside)="closeAccountCard()" class="icon-container">
|
||||||
<div class="avatar-wrapper dontcloseonclick" (click)="showAccount = !showAccount">
|
<app-avatar *ngIf="user && (user.displayName || (user.firstName && user.lastName))"
|
||||||
<div class="avatar-circle dontcloseonclick" [ngClass]="{'active': showAccount}">
|
class="avatar dontcloseonclick" (click)="showAccount = !showAccount" [active]="showAccount"
|
||||||
<i *ngIf="componentCssClass == 'dark-theme'; else lighttheme"
|
[name]="user.displayName ? user.displayName : (user.firstName + ' '+ user.lastName)" [size]="38">
|
||||||
class="avatar dontcloseonclick las la-user-circle"></i>
|
</app-avatar>
|
||||||
|
<app-accounts-card @accounts class="a_card mat-elevation-z5" *ngIf="showAccount"
|
||||||
<ng-template #lighttheme>
|
(close)="showAccount = false" [profile]="profile" [iamuser]="iamreadwrite">
|
||||||
<i class="avatar las la-user-circle"></i>
|
</app-accounts-card>
|
||||||
</ng-template>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<app-accounts-card @accounts class="a_card mat-elevation-z5" *ngIf="showAccount" (close)="showAccount = false"
|
</mat-toolbar>
|
||||||
[profile]="profile" [iamuser]="iamreadwrite">
|
|
||||||
</app-accounts-card>
|
|
||||||
</div>
|
|
||||||
</mat-toolbar>
|
|
||||||
|
|
||||||
<mat-drawer-container *ngIf="(authService.user | async) || {} as user" class="main-container">
|
<mat-drawer-container class="main-container">
|
||||||
<mat-drawer #drawer class="side" [mode]="(isHandset$ | async) ? 'over' : 'side'" [opened]="!(isHandset$ | async)">
|
<mat-drawer #drawer class="side" [mode]="(isHandset$ | async) ? 'over' : 'side'"
|
||||||
<div class="side-column">
|
[opened]="!(isHandset$ | async)">
|
||||||
<div class="list">
|
<div class="side-column">
|
||||||
<a *ngIf="authService.authenticationChanged | async" class="nav-item" [routerLinkActive]="['active']"
|
<div class="list">
|
||||||
[routerLinkActiveOptions]="{ exact: true }" [routerLink]="['/user/me']">
|
<a *ngIf="authService.authenticationChanged | async" class="nav-item"
|
||||||
<i class="icon las la-user-circle"></i>
|
[routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }"
|
||||||
<span class="label">{{ 'MENU.PERSONAL_INFO' | translate }}</span>
|
[routerLink]="['/user/me']">
|
||||||
</a>
|
<i class="icon las la-user-circle"></i>
|
||||||
|
<span class="label">{{ 'MENU.PERSONAL_INFO' | translate }}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
<a *ngIf="iamreadwrite" class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/iam']">
|
<div class="divider"><span></span></div>
|
||||||
<i class="icon las la-gem"></i>
|
|
||||||
<span class="label">{{'MENU.IAM' | translate}}</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a *ngIf="showOrgSection" class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/org']">
|
<a *ngIf="iamreadwrite" class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/iam']">
|
||||||
<i class="icon las la-archway"></i>
|
<i class="icon las la-gem"></i>
|
||||||
<span class="label">{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}</span>
|
<span class="label">{{'MENU.IAM' | translate}}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a *ngIf="showProjectSection" class="nav-item" [routerLinkActive]="['active']"
|
<a *ngIf="showOrgSection" class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/org']">
|
||||||
[routerLink]="[ '/projects']">
|
<i class="icon las la-archway"></i>
|
||||||
<i class="icon las la-layer-group"></i>
|
<span class="label">{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}</span>
|
||||||
<span class="label">{{ 'MENU.PROJECT' | translate }}</span>
|
</a>
|
||||||
</a>
|
|
||||||
|
|
||||||
<a *ngIf="showUserSection" class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/users']"
|
<div class="divider"><span></span></div>
|
||||||
[routerLinkActiveOptions]="{ exact: true }">
|
|
||||||
<i class="icon las la-users"></i>
|
|
||||||
<span class="label">{{ 'MENU.USER' | translate }}</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
|
<a *ngIf="showProjectSection" class="nav-item" [routerLinkActive]="['active']"
|
||||||
|
[routerLink]="[ '/projects']">
|
||||||
|
<i class="icon las la-layer-group"></i>
|
||||||
|
<span class="label">{{ 'MENU.PROJECT' | translate }}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a *ngIf="showProjectSection" class="nav-item" [routerLinkActive]="['active']"
|
||||||
|
[routerLink]="[ '/granted-projects']">
|
||||||
|
<i class="icon las la-layer-group"></i>
|
||||||
|
<span class="label">{{ 'MENU.GRANTEDPROJECT' | translate }}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="divider"><span></span></div>
|
||||||
|
|
||||||
|
<a *ngIf="showUserSection" class="nav-item" [routerLinkActive]="['active']"
|
||||||
|
[routerLink]="[ '/users']" [routerLinkActiveOptions]="{ exact: true }">
|
||||||
|
<i class="icon las la-users"></i>
|
||||||
|
<span class="label">{{ 'MENU.USER' | translate }}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<span class="fill-space"></span>
|
||||||
|
</div>
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
<a class="nav-item" (click)="authService.signout()">
|
<!-- <div class="footer">
|
||||||
<i class="icon las la-sign-out-alt"></i>
|
|
||||||
<span class="label">{{ 'MENU.LOGOUT' | translate }}</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<span class="fill-space"></span>
|
|
||||||
<!-- <div class="footer">
|
|
||||||
<a href="https://caos.ch/impressum/" target="_blank" rel="noreferrer">AGB</a>
|
<a href="https://caos.ch/impressum/" target="_blank" rel="noreferrer">AGB</a>
|
||||||
<a href="https://caos.ch/impressum/" target="_blank" rel="noreferrer">Impressum</a>
|
<a href="https://caos.ch/impressum/" target="_blank" rel="noreferrer">Impressum</a>
|
||||||
</div> -->
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</mat-drawer>
|
</mat-drawer>
|
||||||
<mat-drawer-content class="content">
|
<mat-drawer-content class="content">
|
||||||
<div class="router" [@routeAnimations]="prepareRoute(outlet)">
|
<ng-template appHasRole [appHasRole]="['iam.write']">
|
||||||
<router-outlet #outlet="outlet"></router-outlet>
|
<div class="admin-line" matTooltip="IAM Administrator">
|
||||||
</div>
|
<span>{{'MENU.IAMADMIN' | translate}}</span>
|
||||||
</mat-drawer-content>
|
</div>
|
||||||
</mat-drawer-container>
|
</ng-template>
|
||||||
|
<div class="router" [@routeAnimations]="prepareRoute(outlet)">
|
||||||
|
<router-outlet #outlet="outlet"></router-outlet>
|
||||||
|
</div>
|
||||||
|
</mat-drawer-content>
|
||||||
|
</mat-drawer-container>
|
||||||
|
</ng-container>
|
@@ -31,13 +31,6 @@
|
|||||||
.fill-space {
|
.fill-space {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.iamreadwrite {
|
|
||||||
height: 8px;
|
|
||||||
width: 8px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: linear-gradient(to bottom right, rgb(240,140,53), rgb(233, 60, 231));
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-container {
|
.icon-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -51,44 +44,16 @@
|
|||||||
font-family: 'ailerons', sans-serif;
|
font-family: 'ailerons', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-wrapper {
|
.avatar {
|
||||||
display: flex;
|
display: block;
|
||||||
align-items: center;
|
margin: auto;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.avatar-circle {
|
.name {
|
||||||
height: 30px;
|
font-size: 1rem;
|
||||||
width: 30px;
|
font-weight: 400;
|
||||||
font-size: 30px;
|
}
|
||||||
background-color: transparent;
|
|
||||||
border-radius: 50%;
|
|
||||||
animation: background-color .2s ease-in;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
margin-left: .5rem;
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
display: block;
|
|
||||||
margin: auto auto;
|
|
||||||
height: 30px;
|
|
||||||
width: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
font-size: 30px;
|
|
||||||
border-radius: 50%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover, &.active {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: #ffffff20;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.a_card {
|
.a_card {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -99,6 +64,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.admin-line {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 4px 2rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.main-container {
|
.main-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -239,4 +210,11 @@
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
display: block;
|
||||||
|
background-color: #ffffff10;
|
||||||
|
height: 1px;
|
||||||
|
margin: .5rem 0;
|
||||||
}
|
}
|
@@ -274,7 +274,6 @@ export class AppComponent implements OnDestroy {
|
|||||||
this.translate.setDefaultLang('en');
|
this.translate.setDefaultLang('en');
|
||||||
|
|
||||||
this.authService.user.subscribe(userprofile => {
|
this.authService.user.subscribe(userprofile => {
|
||||||
console.log(userprofile);
|
|
||||||
this.profile = userprofile;
|
this.profile = userprofile;
|
||||||
const lang = userprofile.preferredLanguage.match(/en|de/) ? userprofile.preferredLanguage : 'en';
|
const lang = userprofile.preferredLanguage.match(/en|de/) ? userprofile.preferredLanguage : 'en';
|
||||||
this.translate.use(lang);
|
this.translate.use(lang);
|
||||||
|
@@ -25,6 +25,7 @@ import { AppComponent } from './app.component';
|
|||||||
import { HasRoleModule } from './directives/has-role/has-role.module';
|
import { HasRoleModule } from './directives/has-role/has-role.module';
|
||||||
import { OutsideClickModule } from './directives/outside-click/outside-click.module';
|
import { OutsideClickModule } from './directives/outside-click/outside-click.module';
|
||||||
import { AccountsCardModule } from './modules/accounts-card/accounts-card.module';
|
import { AccountsCardModule } from './modules/accounts-card/accounts-card.module';
|
||||||
|
import { AvatarModule } from './modules/avatar/avatar.module';
|
||||||
import { SignedoutComponent } from './pages/signedout/signedout.component';
|
import { SignedoutComponent } from './pages/signedout/signedout.component';
|
||||||
import { AuthUserService } from './services/auth-user.service';
|
import { AuthUserService } from './services/auth-user.service';
|
||||||
import { AuthService } from './services/auth.service';
|
import { AuthService } from './services/auth.service';
|
||||||
@@ -102,6 +103,7 @@ export const authConfig: AuthConfig = {
|
|||||||
MatToolbarModule,
|
MatToolbarModule,
|
||||||
MatMenuModule,
|
MatMenuModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
|
AvatarModule,
|
||||||
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
|
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
@@ -15,7 +15,6 @@ export class HasRoleDirective {
|
|||||||
this.viewContainerRef.clear();
|
this.viewContainerRef.clear();
|
||||||
this.viewContainerRef.createEmbeddedView(this.templateRef);
|
this.viewContainerRef.createEmbeddedView(this.templateRef);
|
||||||
} else if (this.hasView) {
|
} else if (this.hasView) {
|
||||||
console.log('User blocked!', roles, isAllowed);
|
|
||||||
this.viewContainerRef.clear();
|
this.viewContainerRef.clear();
|
||||||
this.hasView = false;
|
this.hasView = false;
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,6 @@ export class AuthGuard implements CanActivate {
|
|||||||
state: RouterStateSnapshot,
|
state: RouterStateSnapshot,
|
||||||
): Observable<boolean> | Promise<boolean> | boolean {
|
): Observable<boolean> | Promise<boolean> | boolean {
|
||||||
if (!this.auth.authenticated) {
|
if (!this.auth.authenticated) {
|
||||||
console.log('authenticate');
|
|
||||||
return this.auth.authenticate();
|
return this.auth.authenticate();
|
||||||
}
|
}
|
||||||
return this.auth.authenticated;
|
return this.auth.authenticated;
|
||||||
|
@@ -1,12 +1,15 @@
|
|||||||
<div class="card" appOutsideClick (clickOutside)="closeCard($event)">
|
<div class="card" appOutsideClick (clickOutside)="closeCard($event)">
|
||||||
<mat-icon class="avatar">account_circle</mat-icon>
|
<app-avatar *ngIf="profile && (profile.displayName || (profile.firstName && profile.lastName))" class="avatar"
|
||||||
|
[name]="profile.displayName ? profile.displayName : (profile.firstName + ' '+ profile.lastName)" [size]="80">
|
||||||
|
</app-avatar>
|
||||||
|
|
||||||
<span class="u-name">{{profile?.firstName}} {{profile?.lastName}}</span>
|
<span class="u-name">{{profile?.firstName}} {{profile?.lastName}}</span>
|
||||||
<span class="u-email">{{profile?.userName}}</span>
|
<span class="u-email">{{profile?.userName}}</span>
|
||||||
<span class="iamuser" *ngIf="iamuser">IAM USER</span>
|
<span class="iamuser" *ngIf="iamuser">IAM USER</span>
|
||||||
|
|
||||||
<button color="accent" (click)="editUserProfile()" mat-stroked-button>{{'USER.EDITACCOUNT' | translate}}</button>
|
<button color="primary" (click)="editUserProfile()" mat-stroked-button>{{'USER.EDITACCOUNT' | translate}}</button>
|
||||||
<div class="l-accounts">
|
<div class="l-accounts">
|
||||||
<mat-progress-bar *ngIf="loadingUsers" color="accent" mode="indeterminate"></mat-progress-bar>
|
<mat-progress-bar *ngIf="loadingUsers" color="primary" mode="indeterminate"></mat-progress-bar>
|
||||||
<a class="row" *ngFor="let user of users" (click)="selectAccount(user.userName)">
|
<a class="row" *ngFor="let user of users" (click)="selectAccount(user.userName)">
|
||||||
<i class="small-avatar las la-user-circle"></i>
|
<i class="small-avatar las la-user-circle"></i>
|
||||||
|
|
||||||
@@ -29,5 +32,5 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button color="accent" (click)="logout()" mat-stroked-button>logout everywhere</button>
|
<button color="primary" (click)="logout()" mat-stroked-button>{{'MENU.LOGOUT' | translate}}</button>
|
||||||
</div>
|
</div>
|
@@ -10,10 +10,6 @@
|
|||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
height: 80px;
|
|
||||||
width: 80px;
|
|
||||||
border-radius: 50%;
|
|
||||||
line-height: 80px;
|
|
||||||
font-size: 80px;
|
font-size: 80px;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
@@ -30,9 +26,6 @@
|
|||||||
|
|
||||||
.iamuser {
|
.iamuser {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
background: -webkit-linear-gradient(rgb(240,140,53), rgb(233, 60, 231));
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
-webkit-text-fill-color: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
@@ -60,7 +60,7 @@ export class AccountsCardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public logout(): void {
|
public logout(): void {
|
||||||
this.router.navigate(['/']);
|
this.authService.signout();
|
||||||
this.close.emit();
|
this.close.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { OutsideClickModule } from 'src/app/directives/outside-click/outside-click.module';
|
import { OutsideClickModule } from 'src/app/directives/outside-click/outside-click.module';
|
||||||
|
|
||||||
|
import { AvatarModule } from '../avatar/avatar.module';
|
||||||
import { AccountsCardComponent } from './accounts-card.component';
|
import { AccountsCardComponent } from './accounts-card.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -18,6 +19,7 @@ import { AccountsCardComponent } from './accounts-card.component';
|
|||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatProgressBarModule,
|
MatProgressBarModule,
|
||||||
OutsideClickModule,
|
OutsideClickModule,
|
||||||
|
AvatarModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
|
@@ -42,14 +42,12 @@ export class MemberCreateDialogComponent {
|
|||||||
} else if (this.creationType === CreationType.PROJECT_OWNED) {
|
} else if (this.creationType === CreationType.PROJECT_OWNED) {
|
||||||
this.projectService.GetProjectMemberRoles().then(resp => {
|
this.projectService.GetProjectMemberRoles().then(resp => {
|
||||||
this.memberRoleOptions = resp.toObject().rolesList;
|
this.memberRoleOptions = resp.toObject().rolesList;
|
||||||
console.log(this.memberRoleOptions);
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
toastService.showError(error.message);
|
toastService.showError(error.message);
|
||||||
});
|
});
|
||||||
} else if (this.creationType === CreationType.IAM) {
|
} else if (this.creationType === CreationType.IAM) {
|
||||||
this.adminService.GetIamMemberRoles().then(resp => {
|
this.adminService.GetIamMemberRoles().then(resp => {
|
||||||
this.memberRoleOptions = resp.toObject().rolesList;
|
this.memberRoleOptions = resp.toObject().rolesList;
|
||||||
console.log(this.memberRoleOptions);
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
toastService.showError(error.message);
|
toastService.showError(error.message);
|
||||||
});
|
});
|
||||||
|
4
console/src/app/modules/avatar/avatar.component.html
Normal file
4
console/src/app/modules/avatar/avatar.component.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<div class="avatar-circle dontcloseonclick"
|
||||||
|
[ngStyle]="{'height': size+'px', 'width': size+'px', 'fontSize': fontSize+'px'}" [ngClass]="{'active': active}">
|
||||||
|
{{credentials}}
|
||||||
|
</div>
|
15
console/src/app/modules/avatar/avatar.component.scss
Normal file
15
console/src/app/modules/avatar/avatar.component.scss
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-circle {
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
&.active:hover {
|
||||||
|
border: 2px solid #81868a;
|
||||||
|
}
|
||||||
|
}
|
25
console/src/app/modules/avatar/avatar.component.spec.ts
Normal file
25
console/src/app/modules/avatar/avatar.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AvatarComponent } from './avatar.component';
|
||||||
|
|
||||||
|
describe('AvatarComponent', () => {
|
||||||
|
let component: AvatarComponent;
|
||||||
|
let fixture: ComponentFixture<AvatarComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [AvatarComponent],
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AvatarComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
26
console/src/app/modules/avatar/avatar.component.ts
Normal file
26
console/src/app/modules/avatar/avatar.component.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-avatar',
|
||||||
|
templateUrl: './avatar.component.html',
|
||||||
|
styleUrls: ['./avatar.component.scss'],
|
||||||
|
})
|
||||||
|
export class AvatarComponent implements OnInit {
|
||||||
|
@Input() name: string = '';
|
||||||
|
@Input() credentials: string = '';
|
||||||
|
@Input() size: number = 24;
|
||||||
|
@Input() fontSize: number = 16;
|
||||||
|
@Input() active: boolean = false;
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
if (!this.credentials) {
|
||||||
|
const split: string[] = this.name.split(' ');
|
||||||
|
this.credentials = split[0].charAt(0) + (split[1] ? split[1].charAt(0) : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.size > 50) {
|
||||||
|
this.fontSize = 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
console/src/app/modules/avatar/avatar.module.ts
Normal file
18
console/src/app/modules/avatar/avatar.module.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
|
import { AvatarComponent } from './avatar.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [AvatarComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
AvatarComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AvatarModule { }
|
||||||
|
|
@@ -6,12 +6,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.scroll-container {
|
.scroll-container {
|
||||||
max-height: 540px;
|
max-height: 60vh;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
height: 50px;
|
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
margin: .25rem 0;
|
margin: .25rem 0;
|
||||||
border-radius: .5rem;
|
border-radius: .5rem;
|
||||||
|
@@ -20,6 +20,7 @@ export class ChangesComponent implements OnInit {
|
|||||||
@Input() public id: string = '';
|
@Input() public id: string = '';
|
||||||
@Input() public sortDirectionAsc: boolean = true;
|
@Input() public sortDirectionAsc: boolean = true;
|
||||||
public errorMessage: string = '';
|
public errorMessage: string = '';
|
||||||
|
public bottom: boolean = false;
|
||||||
|
|
||||||
// Source data
|
// Source data
|
||||||
private _done: BehaviorSubject<any> = new BehaviorSubject(false);
|
private _done: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||||
@@ -93,36 +94,36 @@ export class ChangesComponent implements OnInit {
|
|||||||
private mapAndUpdate(col: Promise<Changes>): any {
|
private mapAndUpdate(col: Promise<Changes>): any {
|
||||||
if (this._done.value || this._loading.value) { return; }
|
if (this._done.value || this._loading.value) { return; }
|
||||||
|
|
||||||
// loading
|
|
||||||
this._loading.next(true);
|
|
||||||
|
|
||||||
// Map snapshot with doc ref (needed for cursor)
|
// Map snapshot with doc ref (needed for cursor)
|
||||||
return from(col).pipe(
|
if (!this.bottom) {
|
||||||
tap((res: Changes) => {
|
// loading
|
||||||
console.log('more changes');
|
this._loading.next(true);
|
||||||
let values = res.toObject().changesList;
|
|
||||||
// If prepending, reverse the batch order
|
|
||||||
values = false ? values.reverse() : values;
|
|
||||||
|
|
||||||
// update source with new values, done loading
|
return from(col).pipe(
|
||||||
this._data.next(values);
|
tap((res: Changes) => {
|
||||||
console.log(values);
|
let values = res.toObject().changesList;
|
||||||
|
// If prepending, reverse the batch order
|
||||||
|
values = false ? values.reverse() : values;
|
||||||
|
|
||||||
// console.log(values);
|
// update source with new values, done loading
|
||||||
this._loading.next(false);
|
this._data.next(values);
|
||||||
|
|
||||||
// no more values, mark done
|
this._loading.next(false);
|
||||||
if (!values.length) {
|
|
||||||
this._done.next(true);
|
// no more values, mark done
|
||||||
}
|
if (!values.length) {
|
||||||
}),
|
this._done.next(true);
|
||||||
catchError(err => {
|
}
|
||||||
console.error(err);
|
}),
|
||||||
this._loading.next(false);
|
catchError(err => {
|
||||||
this.errorMessage = err.message;
|
console.error(err);
|
||||||
return of([]);
|
this._loading.next(false);
|
||||||
}),
|
this.errorMessage = decodeURI(err.message);
|
||||||
take(1),
|
this.bottom = true;
|
||||||
).subscribe();
|
return of([]);
|
||||||
|
}),
|
||||||
|
take(1),
|
||||||
|
).subscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
</div>
|
</div>
|
||||||
<div class="meta" [ngClass]="{'hidden': hidden}">
|
<div class="meta" [ngClass]="{'hidden': hidden}">
|
||||||
<button (click)="hidden = !hidden" color="accent" class="hide" mat-icon-button><i
|
<button (click)="hidden = !hidden" color="primary" class="hide" mat-icon-button><i
|
||||||
class="las la-arrow-right"></i></button>
|
class="las la-arrow-right"></i></button>
|
||||||
<ng-content class="meta-content" select="metainfo"></ng-content>
|
<ng-content class="meta-content" select="metainfo"></ng-content>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.meta {
|
.meta {
|
||||||
overflow-y: hidden;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 1 0 300px;
|
flex: 1 0 300px;
|
||||||
background: linear-gradient(to bottom right, #4072b410 20%,transparent 50%);
|
background: linear-gradient(to bottom right, #4072b410 20%,transparent 50%);
|
||||||
|
@@ -7,7 +7,11 @@
|
|||||||
<ng-container *ngFor="let member of membersSubject | async">
|
<ng-container *ngFor="let member of membersSubject | async">
|
||||||
<div (click)="showDetail()" class="avatar-circle"
|
<div (click)="showDetail()" class="avatar-circle"
|
||||||
matTooltip="{{ member.email }} | {{member.rolesList?.join(' ')}}">
|
matTooltip="{{ member.email }} | {{member.rolesList?.join(' ')}}">
|
||||||
<i class="avatar las la-user-circle"></i>
|
<app-avatar *ngIf="member && (member.displayName || (member.firstName && member.lastName))"
|
||||||
|
class="avatar dontcloseonclick"
|
||||||
|
[name]="member.displayName ? member.displayName : (member.firstName + ' '+ member.lastName)"
|
||||||
|
[size]="32">
|
||||||
|
</app-avatar>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
@@ -15,10 +15,7 @@ import {
|
|||||||
import { ProjectService } from 'src/app/services/project.service';
|
import { ProjectService } from 'src/app/services/project.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
|
|
||||||
import {
|
import { CreationType, MemberCreateDialogComponent } from '../../modules/add-member-dialog/member-create-dialog.component';
|
||||||
CreationType,
|
|
||||||
MemberCreateDialogComponent,
|
|
||||||
} from '../../../modules/add-member-dialog/member-create-dialog.component';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-project-contributors',
|
selector: 'app-project-contributors',
|
||||||
@@ -43,7 +40,6 @@ export class ProjectContributorsComponent implements OnInit {
|
|||||||
private router: Router) { }
|
private router: Router) { }
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
console.log('project grant members');
|
|
||||||
const promise: Promise<ProjectMemberSearchResponse> | undefined =
|
const promise: Promise<ProjectMemberSearchResponse> | undefined =
|
||||||
this.projectType === ProjectType.PROJECTTYPE_OWNED ?
|
this.projectType === ProjectType.PROJECTTYPE_OWNED ?
|
||||||
this.projectService.SearchProjectMembers(this.project.projectId, 100, 0) :
|
this.projectService.SearchProjectMembers(this.project.projectId, 100, 0) :
|
||||||
@@ -59,7 +55,6 @@ export class ProjectContributorsComponent implements OnInit {
|
|||||||
catchError(() => of([])),
|
catchError(() => of([])),
|
||||||
finalize(() => this.loadingSubject.next(false)),
|
finalize(() => this.loadingSubject.next(false)),
|
||||||
).subscribe(members => {
|
).subscribe(members => {
|
||||||
console.log(members);
|
|
||||||
this.membersSubject.next(members);
|
this.membersSubject.next(members);
|
||||||
});
|
});
|
||||||
}
|
}
|
@@ -0,0 +1,30 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { MemberCreateDialogModule } from '../add-member-dialog/member-create-dialog.module';
|
||||||
|
import { AvatarModule } from '../avatar/avatar.module';
|
||||||
|
import { ProjectContributorsComponent } from './project-contributors.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [ProjectContributorsComponent],
|
||||||
|
imports: [
|
||||||
|
MemberCreateDialogModule,
|
||||||
|
CommonModule,
|
||||||
|
TranslateModule,
|
||||||
|
MatTooltipModule,
|
||||||
|
MatIconModule,
|
||||||
|
MatButtonModule,
|
||||||
|
AvatarModule,
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
ProjectContributorsComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class ProjectContributorsModule { }
|
||||||
|
|
@@ -36,7 +36,6 @@ export class ProjectMembersDataSource extends DataSource<ProjectMember.AsObject>
|
|||||||
from(promise).pipe(
|
from(promise).pipe(
|
||||||
map(resp => {
|
map(resp => {
|
||||||
this.totalResult = resp.toObject().totalResult;
|
this.totalResult = resp.toObject().totalResult;
|
||||||
console.log(this.totalResult);
|
|
||||||
return resp.toObject().resultList;
|
return resp.toObject().resultList;
|
||||||
}),
|
}),
|
||||||
catchError(() => of([])),
|
catchError(() => of([])),
|
@@ -33,7 +33,6 @@ export class ProjectMembersComponent implements AfterViewInit {
|
|||||||
this.route.params.subscribe(params => {
|
this.route.params.subscribe(params => {
|
||||||
this.projectService.GetProjectById(params.projectid).then(project => {
|
this.projectService.GetProjectById(params.projectid).then(project => {
|
||||||
this.project = project.toObject();
|
this.project = project.toObject();
|
||||||
console.log(this.project);
|
|
||||||
this.dataSource = new ProjectMembersDataSource(this.projectService);
|
this.dataSource = new ProjectMembersDataSource(this.projectService);
|
||||||
this.dataSource.loadMembers(this.project, this.projectType, 0, 25, 'asc');
|
this.dataSource.loadMembers(this.project, this.projectType, 0, 25, 'asc');
|
||||||
});
|
});
|
@@ -31,7 +31,6 @@ export class ProjectRolesDataSource extends DataSource<ProjectRole.AsObject> {
|
|||||||
catchError(() => of([])),
|
catchError(() => of([])),
|
||||||
finalize(() => this.loadingSubject.next(false)),
|
finalize(() => this.loadingSubject.next(false)),
|
||||||
).subscribe(roles => {
|
).subscribe(roles => {
|
||||||
console.log(roles);
|
|
||||||
this.rolesSubject.next(roles);
|
this.rolesSubject.next(roles);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -48,7 +48,6 @@ export class SearchProjectAutocompleteComponent {
|
|||||||
}),
|
}),
|
||||||
// finalize(() => this.isLoading = false),
|
// finalize(() => this.isLoading = false),
|
||||||
).subscribe((projects) => {
|
).subscribe((projects) => {
|
||||||
console.log(projects.toObject().resultList);
|
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.filteredProjects = projects.toObject().resultList;
|
this.filteredProjects = projects.toObject().resultList;
|
||||||
});
|
});
|
||||||
|
@@ -48,11 +48,9 @@ export class SearchRolesAutocompleteComponent {
|
|||||||
return from(this.projectService.SearchProjectRoles(this.projectId, 10, 0, [query]));
|
return from(this.projectService.SearchProjectRoles(this.projectId, 10, 0, [query]));
|
||||||
}),
|
}),
|
||||||
).subscribe((roles) => {
|
).subscribe((roles) => {
|
||||||
console.log(roles.toObject().resultList);
|
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.filteredRoles = roles.toObject().resultList;
|
this.filteredRoles = roles.toObject().resultList;
|
||||||
}, error => {
|
}, error => {
|
||||||
console.log(error);
|
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -99,8 +99,6 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
|||||||
this.oidcApp.responseTypesList = this.responseTypesList?.value;
|
this.oidcApp.responseTypesList = this.responseTypesList?.value;
|
||||||
this.oidcApp.authMethodType = this.authMethodType?.value;
|
this.oidcApp.authMethodType = this.authMethodType?.value;
|
||||||
|
|
||||||
console.log(this.oidcApp);
|
|
||||||
|
|
||||||
this.projectService
|
this.projectService
|
||||||
.CreateOIDCApp(this.oidcApp)
|
.CreateOIDCApp(this.oidcApp)
|
||||||
.then((data: Application) => {
|
.then((data: Application) => {
|
||||||
@@ -119,7 +117,6 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
console.log('The dialog was closed');
|
|
||||||
this.router.navigate(['projects', this.projectId, 'apps', app.id]);
|
this.router.navigate(['projects', this.projectId, 'apps', app.id]);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@@ -118,7 +118,6 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
|||||||
this.projectService.GetApplicationById(projectid, id).then(app => {
|
this.projectService.GetApplicationById(projectid, id).then(app => {
|
||||||
this.app = app.toObject();
|
this.app = app.toObject();
|
||||||
this.appNameForm.patchValue(this.app);
|
this.appNameForm.patchValue(this.app);
|
||||||
console.log(this.grpcService.clientid, this.app.oidcConfig?.clientId);
|
|
||||||
|
|
||||||
if (this.app.state !== AppState.APPSTATE_ACTIVE) {
|
if (this.app.state !== AppState.APPSTATE_ACTIVE) {
|
||||||
this.appNameForm.controls['name'].disable();
|
this.appNameForm.controls['name'].disable();
|
||||||
@@ -220,8 +219,6 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
|||||||
this.app.oidcConfig.redirectUrisList = this.redirectUrisList;
|
this.app.oidcConfig.redirectUrisList = this.redirectUrisList;
|
||||||
this.app.oidcConfig.postLogoutRedirectUrisList = this.postLogoutRedirectUrisList;
|
this.app.oidcConfig.postLogoutRedirectUrisList = this.postLogoutRedirectUrisList;
|
||||||
|
|
||||||
console.log(this.app.oidcConfig);
|
|
||||||
|
|
||||||
this.projectService
|
this.projectService
|
||||||
.UpdateOIDCAppConfig(this.projectId, this.app.id, this.app.oidcConfig)
|
.UpdateOIDCAppConfig(this.projectId, this.app.id, this.app.oidcConfig)
|
||||||
.then((data: OIDCConfig) => {
|
.then((data: OIDCConfig) => {
|
||||||
@@ -235,9 +232,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public regenerateOIDCClientSecret(): void {
|
public regenerateOIDCClientSecret(): void {
|
||||||
console.log(this.app.id, this.projectId);
|
|
||||||
this.projectService.RegenerateOIDCClientSecret(this.app.id, this.projectId).then((data: OIDCConfig) => {
|
this.projectService.RegenerateOIDCClientSecret(this.app.id, this.projectId).then((data: OIDCConfig) => {
|
||||||
console.log(data.toObject());
|
|
||||||
this.toast.showInfo('OIDC Secret Regenerated');
|
this.toast.showInfo('OIDC Secret Regenerated');
|
||||||
this.dialog.open(AppSecretDialogComponent, {
|
this.dialog.open(AppSecretDialogComponent, {
|
||||||
data: {
|
data: {
|
||||||
|
@@ -86,7 +86,6 @@ export class GrantedProjectDetailComponent implements OnInit, OnDestroy {
|
|||||||
if (this.projectId && this.grantId) {
|
if (this.projectId && this.grantId) {
|
||||||
this.projectService.GetGrantedProjectByID(this.projectId, this.grantId).then(proj => {
|
this.projectService.GetGrantedProjectByID(this.projectId, this.grantId).then(proj => {
|
||||||
this.project = proj.toObject();
|
this.project = proj.toObject();
|
||||||
console.log(this.project);
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error.message);
|
this.toast.showError(error.message);
|
||||||
});
|
});
|
@@ -90,7 +90,6 @@ export class GrantedProjectListComponent implements OnInit, OnDestroy {
|
|||||||
this.totalResult = res.toObject().totalResult;
|
this.totalResult = res.toObject().totalResult;
|
||||||
this.dataSource.data = this.grantedProjectList;
|
this.dataSource.data = this.grantedProjectList;
|
||||||
this.loadingSubject.next(false);
|
this.loadingSubject.next(false);
|
||||||
console.log(this.grantedProjectList);
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
this.toast.showError(error.message);
|
this.toast.showError(error.message);
|
@@ -0,0 +1,48 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { AuthGuard } from 'src/app/guards/auth.guard';
|
||||||
|
import { RoleGuard } from 'src/app/guards/role.guard';
|
||||||
|
|
||||||
|
import { GrantedProjectDetailComponent } from './granted-project-detail/granted-project-detail.component';
|
||||||
|
import { GrantedProjectsComponent } from './granted-projects.component';
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: GrantedProjectsComponent,
|
||||||
|
data: { animation: 'HomePage' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'create',
|
||||||
|
loadChildren: () => import('../project-create/project-create.module').then(m => m.ProjectCreateModule),
|
||||||
|
canActivate: [AuthGuard, RoleGuard],
|
||||||
|
data: {
|
||||||
|
roles: ['project.write'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':id/grant/:grantId',
|
||||||
|
component: GrantedProjectDetailComponent,
|
||||||
|
data: { animation: 'HomePage' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':projectid/members',
|
||||||
|
loadChildren: () => import('../../modules/project-members/project-members.module').then(m => m.ProjectMembersModule),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':projectid/roles/create',
|
||||||
|
loadChildren: () => import('../project-role-create/project-role-create.module').then(m => m.ProjectRoleCreateModule),
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':projectid/grants/create',
|
||||||
|
loadChildren: () => import('../project-grant-create/project-grant-create.module')
|
||||||
|
.then(m => m.ProjectGrantCreateModule),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(routes)],
|
||||||
|
exports: [RouterModule],
|
||||||
|
})
|
||||||
|
export class GrantedProjectsRoutingModule { }
|
@@ -2,9 +2,6 @@
|
|||||||
<h1>{{ 'PROJECT.PAGES.LIST' | translate }}</h1>
|
<h1>{{ 'PROJECT.PAGES.LIST' | translate }}</h1>
|
||||||
<p class="sub">{{ 'PROJECT.PAGES.LISTDESCRIPTION' | translate }}</p>
|
<p class="sub">{{ 'PROJECT.PAGES.LISTDESCRIPTION' | translate }}</p>
|
||||||
|
|
||||||
<h2>Owned Projects</h2>
|
|
||||||
<app-owned-project-list></app-owned-project-list>
|
|
||||||
|
|
||||||
<h2>Granted Projects</h2>
|
<h2>Granted Projects</h2>
|
||||||
<app-granted-project-list>
|
<app-granted-project-list>
|
||||||
</app-granted-project-list>
|
</app-granted-project-list>
|
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { GrantedProjectsComponent } from './granted-projects.component';
|
||||||
|
|
||||||
|
describe('GrantedProjectsComponent', () => {
|
||||||
|
let component: GrantedProjectsComponent;
|
||||||
|
let fixture: ComponentFixture<GrantedProjectsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [GrantedProjectsComponent],
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(GrantedProjectsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,29 @@
|
|||||||
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-granted-projects',
|
||||||
|
templateUrl: './granted-projects.component.html',
|
||||||
|
styleUrls: ['./granted-projects.component.scss'],
|
||||||
|
})
|
||||||
|
export class GrantedProjectsComponent implements OnInit, OnDestroy {
|
||||||
|
// public projectId: string = '';
|
||||||
|
// public grantId: string = '';
|
||||||
|
private sub: Subscription = new Subscription();
|
||||||
|
constructor(private route: ActivatedRoute,
|
||||||
|
) {
|
||||||
|
// this.route.params.subscribe((params) => {
|
||||||
|
// this.projectId = params.projectId;
|
||||||
|
// this.grantId = params.grantId;
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ngOnDestroy(): void {
|
||||||
|
// this.sub.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,91 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||||
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||||
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
|
import { MatSortModule } from '@angular/material/sort';
|
||||||
|
import { MatTableModule } from '@angular/material/table';
|
||||||
|
import { MatTabsModule } from '@angular/material/tabs';
|
||||||
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { HttpLoaderFactory } from '../../app.module';
|
||||||
|
import { HasRoleModule } from '../../directives/has-role/has-role.module';
|
||||||
|
import { CardModule } from '../../modules/card/card.module';
|
||||||
|
import { ChangesModule } from '../../modules/changes/changes.module';
|
||||||
|
import { MetaLayoutModule } from '../../modules/meta-layout/meta-layout.module';
|
||||||
|
import { ProjectContributorsModule } from '../../modules/project-contributors/project-contributors.module';
|
||||||
|
import { ProjectRolesModule } from '../../modules/project-roles/project-roles.module';
|
||||||
|
import { SearchUserAutocompleteModule } from '../../modules/search-user-autocomplete/search-user-autocomplete.module';
|
||||||
|
import { PipesModule } from '../../pipes/pipes.module';
|
||||||
|
import { OrgContributorsModule } from '../orgs/org-contributors/org-contributors.module';
|
||||||
|
import { UserListModule } from '../user-list/user-list.module';
|
||||||
|
import { GrantedProjectDetailComponent } from './granted-project-detail/granted-project-detail.component';
|
||||||
|
import { GrantedProjectGridComponent } from './granted-project-grid/granted-project-grid.component';
|
||||||
|
import { GrantedProjectListComponent } from './granted-project-list/granted-project-list.component';
|
||||||
|
import { GrantedProjectsRoutingModule } from './granted-projects-routing.module';
|
||||||
|
import { GrantedProjectsComponent } from './granted-projects.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
GrantedProjectsComponent,
|
||||||
|
GrantedProjectListComponent,
|
||||||
|
GrantedProjectGridComponent,
|
||||||
|
GrantedProjectDetailComponent,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
GrantedProjectsRoutingModule,
|
||||||
|
ProjectContributorsModule,
|
||||||
|
FormsModule,
|
||||||
|
TranslateModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
HasRoleModule,
|
||||||
|
MatTableModule,
|
||||||
|
MatPaginatorModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
|
ChangesModule,
|
||||||
|
UserListModule,
|
||||||
|
MatMenuModule,
|
||||||
|
MatChipsModule,
|
||||||
|
MatIconModule,
|
||||||
|
MatSelectModule,
|
||||||
|
MatButtonModule,
|
||||||
|
MatProgressSpinnerModule,
|
||||||
|
MetaLayoutModule,
|
||||||
|
MatProgressBarModule,
|
||||||
|
MatDialogModule,
|
||||||
|
MatButtonToggleModule,
|
||||||
|
MatTabsModule,
|
||||||
|
ProjectRolesModule,
|
||||||
|
SearchUserAutocompleteModule,
|
||||||
|
MatCheckboxModule,
|
||||||
|
CardModule,
|
||||||
|
MatTooltipModule,
|
||||||
|
MatSortModule,
|
||||||
|
PipesModule,
|
||||||
|
OrgContributorsModule,
|
||||||
|
TranslateModule.forChild({
|
||||||
|
loader: {
|
||||||
|
provide: TranslateLoader,
|
||||||
|
useFactory: HttpLoaderFactory,
|
||||||
|
deps: [HttpClient],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
|
})
|
||||||
|
export class GrantedProjectsModule { }
|
@@ -34,7 +34,6 @@ export class ProjectGrantMembersDataSource extends DataSource<ProjectMember.AsOb
|
|||||||
catchError(() => of([])),
|
catchError(() => of([])),
|
||||||
finalize(() => this.loadingSubject.next(false)),
|
finalize(() => this.loadingSubject.next(false)),
|
||||||
).subscribe(members => {
|
).subscribe(members => {
|
||||||
console.log(members);
|
|
||||||
this.membersSubject.next(members);
|
this.membersSubject.next(members);
|
||||||
});
|
});
|
||||||
|
|
@@ -101,7 +101,6 @@ export class ProjectGrantMembersComponent implements AfterViewInit, OnInit {
|
|||||||
|
|
||||||
dialogRef.afterClosed().subscribe(resp => {
|
dialogRef.afterClosed().subscribe(resp => {
|
||||||
if (resp) {
|
if (resp) {
|
||||||
console.log(resp);
|
|
||||||
const users: User.AsObject[] = resp.users;
|
const users: User.AsObject[] = resp.users;
|
||||||
const roles: string[] = resp.roles;
|
const roles: string[] = resp.roles;
|
||||||
|
|
@@ -4,7 +4,6 @@
|
|||||||
<ng-template #lighttheme>
|
<ng-template #lighttheme>
|
||||||
<img src="../assets/images/zitadel-logo-oneline-lightdesign.svg" />
|
<img src="../assets/images/zitadel-logo-oneline-lightdesign.svg" />
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<p>{{'HOME.DESCRIPTION' | translate}}</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@@ -53,8 +53,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
height: 90px;
|
height: 60px;
|
||||||
margin-bottom: 2rem;
|
align-self: flex-end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,14 +73,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
transition: border-color .1s;
|
transition: border-color .1s;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
i {
|
|
||||||
color: #fe11e280;
|
|
||||||
}
|
|
||||||
// border-width: 2px;
|
|
||||||
border-color: #fe11e270;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top {
|
.top {
|
||||||
padding: 1rem 2rem;
|
padding: 1rem 2rem;
|
||||||
|
@@ -7,7 +7,11 @@
|
|||||||
<ng-container *ngFor="let member of membersSubject | async">
|
<ng-container *ngFor="let member of membersSubject | async">
|
||||||
<div (click)="showDetail()" class="avatar-circle"
|
<div (click)="showDetail()" class="avatar-circle"
|
||||||
matTooltip="{{ member.email }} | {{member.rolesList?.join(' ')}}">
|
matTooltip="{{ member.email }} | {{member.rolesList?.join(' ')}}">
|
||||||
<i class="avatar las la-user-circle"></i>
|
<app-avatar *ngIf="member && (member.displayName || (member.firstName && member.lastName))"
|
||||||
|
class="avatar dontcloseonclick"
|
||||||
|
[name]="member.displayName ? member.displayName : (member.firstName + ' '+ member.lastName)"
|
||||||
|
[size]="32">
|
||||||
|
</app-avatar>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@@ -53,7 +53,6 @@ export class IamContributorsComponent implements OnInit {
|
|||||||
catchError(() => of([])),
|
catchError(() => of([])),
|
||||||
finalize(() => this.loadingSubject.next(false)),
|
finalize(() => this.loadingSubject.next(false)),
|
||||||
).subscribe(members => {
|
).subscribe(members => {
|
||||||
console.log(members);
|
|
||||||
this.membersSubject.next(members);
|
this.membersSubject.next(members);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
|||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
|
import { AvatarModule } from 'src/app/modules/avatar/avatar.module';
|
||||||
|
|
||||||
import { MemberCreateDialogModule } from '../../../modules/add-member-dialog/member-create-dialog.module';
|
import { MemberCreateDialogModule } from '../../../modules/add-member-dialog/member-create-dialog.module';
|
||||||
import { IamContributorsComponent } from './iam-contributors.component';
|
import { IamContributorsComponent } from './iam-contributors.component';
|
||||||
@@ -30,6 +31,7 @@ import { IamContributorsComponent } from './iam-contributors.component';
|
|||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
|
AvatarModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
|
@@ -32,7 +32,6 @@ export class IamMembersDataSource extends DataSource<ProjectMember.AsObject> {
|
|||||||
from(promise).pipe(
|
from(promise).pipe(
|
||||||
map(resp => {
|
map(resp => {
|
||||||
this.totalResult = resp.toObject().totalResult;
|
this.totalResult = resp.toObject().totalResult;
|
||||||
console.log(this.totalResult);
|
|
||||||
return resp.toObject().resultList;
|
return resp.toObject().resultList;
|
||||||
}),
|
}),
|
||||||
catchError(() => of([])),
|
catchError(() => of([])),
|
||||||
|
@@ -7,7 +7,11 @@
|
|||||||
<ng-container *ngFor="let member of membersSubject | async">
|
<ng-container *ngFor="let member of membersSubject | async">
|
||||||
<div (click)="showDetail()" class="avatar-circle"
|
<div (click)="showDetail()" class="avatar-circle"
|
||||||
matTooltip="{{ member.email }} | {{member.rolesList?.join(' ')}}">
|
matTooltip="{{ member.email }} | {{member.rolesList?.join(' ')}}">
|
||||||
<i class="avatar las la-user-circle"></i>
|
<app-avatar *ngIf="member && (member.displayName || (member.firstName && member.lastName))"
|
||||||
|
class="avatar dontcloseonclick"
|
||||||
|
[name]="member.displayName ? member.displayName : (member.firstName + ' '+ member.lastName)"
|
||||||
|
[size]="32">
|
||||||
|
</app-avatar>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@@ -54,7 +54,6 @@ export class OrgContributorsComponent implements OnInit {
|
|||||||
catchError(() => of([])),
|
catchError(() => of([])),
|
||||||
finalize(() => this.loadingSubject.next(false)),
|
finalize(() => this.loadingSubject.next(false)),
|
||||||
).subscribe(members => {
|
).subscribe(members => {
|
||||||
console.log(members);
|
|
||||||
this.membersSubject.next(members);
|
this.membersSubject.next(members);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
|||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
|
import { AvatarModule } from 'src/app/modules/avatar/avatar.module';
|
||||||
|
|
||||||
import { MemberCreateDialogModule } from '../../../modules/add-member-dialog/member-create-dialog.module';
|
import { MemberCreateDialogModule } from '../../../modules/add-member-dialog/member-create-dialog.module';
|
||||||
import { OrgContributorsComponent } from './org-contributors.component';
|
import { OrgContributorsComponent } from './org-contributors.component';
|
||||||
@@ -34,6 +35,7 @@ import { OrgContributorsComponent } from './org-contributors.component';
|
|||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
|
AvatarModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
OrgContributorsComponent,
|
OrgContributorsComponent,
|
||||||
|
@@ -100,7 +100,6 @@ export class OrgCreateComponent {
|
|||||||
confirmPassword: ['', [...validators, passwordConfirmValidator]],
|
confirmPassword: ['', [...validators, passwordConfirmValidator]],
|
||||||
});
|
});
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.log('no password complexity policy defined!');
|
|
||||||
console.error(error);
|
console.error(error);
|
||||||
this.userForm = this.fb.group({
|
this.userForm = this.fb.group({
|
||||||
userName: ['', [Validators.required]],
|
userName: ['', [Validators.required]],
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
<input matInput [(ngModel)]="newDomain" />
|
<input matInput [(ngModel)]="newDomain" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<button matTooltip="Add domain" mat-icon-button color="accent" (click)="saveNewOrgDomain()">
|
<button matTooltip="Add domain" mat-icon-button color="primary" (click)="saveNewOrgDomain()">
|
||||||
<mat-icon>check</mat-icon>
|
<mat-icon>check</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
@@ -52,7 +52,6 @@ export class OrgDetailComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.orgService.SearchMyOrgDomains(0, 100).then(result => {
|
this.orgService.SearchMyOrgDomains(0, 100).then(result => {
|
||||||
console.log(result.toObject().resultList);
|
|
||||||
this.domains = result.toObject().resultList;
|
this.domains = result.toObject().resultList;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -81,7 +80,6 @@ export class OrgDetailComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public removeDomain(domain: string): void {
|
public removeDomain(domain: string): void {
|
||||||
console.log(domain);
|
|
||||||
this.orgService.RemoveMyOrgDomain(domain).then(() => {
|
this.orgService.RemoveMyOrgDomain(domain).then(() => {
|
||||||
this.toast.showInfo('Removed');
|
this.toast.showInfo('Removed');
|
||||||
const index = this.domains.findIndex(d => d.domain === domain);
|
const index = this.domains.findIndex(d => d.domain === domain);
|
||||||
|
@@ -31,7 +31,6 @@ export class OrgGridComponent {
|
|||||||
private getData(limit: number, offset: number): void {
|
private getData(limit: number, offset: number): void {
|
||||||
this.userService.SearchMyProjectOrgs(limit, offset).then(res => {
|
this.userService.SearchMyProjectOrgs(limit, offset).then(res => {
|
||||||
this.orgList = res.toObject().resultList;
|
this.orgList = res.toObject().resultList;
|
||||||
console.log(this.orgList);
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
this.toast.showError(error.message);
|
this.toast.showError(error.message);
|
||||||
|
@@ -21,7 +21,6 @@ export class OrgMemberRolesAutocompleteComponent {
|
|||||||
constructor(private orgService: OrgService, private toast: ToastService) {
|
constructor(private orgService: OrgService, private toast: ToastService) {
|
||||||
this.orgService.GetOrgMemberRoles().then(resp => {
|
this.orgService.GetOrgMemberRoles().then(resp => {
|
||||||
this.allRoles = resp.toObject().rolesList;
|
this.allRoles = resp.toObject().rolesList;
|
||||||
console.log(this.allRoles);
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error.message);
|
this.toast.showError(error.message);
|
||||||
});
|
});
|
||||||
|
@@ -31,7 +31,6 @@ export class ProjectMembersDataSource extends DataSource<ProjectMember.AsObject>
|
|||||||
from(promise).pipe(
|
from(promise).pipe(
|
||||||
map(resp => {
|
map(resp => {
|
||||||
this.totalResult = resp.toObject().totalResult;
|
this.totalResult = resp.toObject().totalResult;
|
||||||
console.log(this.totalResult);
|
|
||||||
return resp.toObject().resultList;
|
return resp.toObject().resultList;
|
||||||
}),
|
}),
|
||||||
catchError(() => of([])),
|
catchError(() => of([])),
|
||||||
|
@@ -33,7 +33,6 @@ export class OrgMembersComponent implements AfterViewInit {
|
|||||||
private toast: ToastService) {
|
private toast: ToastService) {
|
||||||
this.orgService.GetMyOrg().then(org => {
|
this.orgService.GetMyOrg().then(org => {
|
||||||
this.org = org.toObject();
|
this.org = org.toObject();
|
||||||
console.log(this.org);
|
|
||||||
this.dataSource = new ProjectMembersDataSource(this.orgService);
|
this.dataSource = new ProjectMembersDataSource(this.orgService);
|
||||||
this.dataSource.loadMembers(0, 25, 'asc');
|
this.dataSource.loadMembers(0, 25, 'asc');
|
||||||
});
|
});
|
||||||
|
@@ -124,7 +124,6 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
|||||||
break;
|
break;
|
||||||
case PolicyComponentType.IAM_POLICY:
|
case PolicyComponentType.IAM_POLICY:
|
||||||
this.iamData = data.toObject();
|
this.iamData = data.toObject();
|
||||||
console.log(this.iamData);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -236,7 +235,6 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case PolicyComponentType.COMPLEXITY:
|
case PolicyComponentType.COMPLEXITY:
|
||||||
console.log(this.complexityData);
|
|
||||||
this.orgService.CreatePasswordComplexityPolicy(
|
this.orgService.CreatePasswordComplexityPolicy(
|
||||||
this.complexityData.description,
|
this.complexityData.description,
|
||||||
this.complexityData.hasLowercase,
|
this.complexityData.hasLowercase,
|
||||||
@@ -252,7 +250,6 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PolicyComponentType.IAM_POLICY:
|
case PolicyComponentType.IAM_POLICY:
|
||||||
console.log(this.complexityData);
|
|
||||||
const orgId = this.sessionStorage.getItem('organization');
|
const orgId = this.sessionStorage.getItem('organization');
|
||||||
if (orgId) {
|
if (orgId) {
|
||||||
this.adminService.CreateOrgIamPolicy(
|
this.adminService.CreateOrgIamPolicy(
|
||||||
@@ -294,7 +291,6 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case PolicyComponentType.COMPLEXITY:
|
case PolicyComponentType.COMPLEXITY:
|
||||||
console.log(this.complexityData);
|
|
||||||
this.orgService.UpdatePasswordComplexityPolicy(
|
this.orgService.UpdatePasswordComplexityPolicy(
|
||||||
this.complexityData.description,
|
this.complexityData.description,
|
||||||
this.complexityData.hasLowercase,
|
this.complexityData.hasLowercase,
|
||||||
@@ -310,7 +306,6 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PolicyComponentType.IAM_POLICY:
|
case PolicyComponentType.IAM_POLICY:
|
||||||
console.log(this.complexityData);
|
|
||||||
const orgId = this.sessionStorage.getItem('organization');
|
const orgId = this.sessionStorage.getItem('organization');
|
||||||
if (orgId) {
|
if (orgId) {
|
||||||
this.adminService.UpdateOrgIamPolicy(
|
this.adminService.UpdateOrgIamPolicy(
|
||||||
|
@@ -85,7 +85,6 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy {
|
|||||||
if (this.projectId) {
|
if (this.projectId) {
|
||||||
this.projectService.GetProjectById(id).then(proj => {
|
this.projectService.GetProjectById(id).then(proj => {
|
||||||
this.project = proj.toObject();
|
this.project = proj.toObject();
|
||||||
console.log(this.project);
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error.message);
|
this.toast.showError(error.message);
|
||||||
});
|
});
|
@@ -56,7 +56,6 @@ export class OwnedProjectListComponent implements OnInit, OnDestroy {
|
|||||||
) { }
|
) { }
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
console.log('asdf');
|
|
||||||
this.getData(10, 0);
|
this.getData(10, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,14 +84,12 @@ export class OwnedProjectListComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async getData(limit: number, offset: number): Promise<void> {
|
private async getData(limit: number, offset: number): Promise<void> {
|
||||||
console.log('getprojects');
|
|
||||||
this.loadingSubject.next(true);
|
this.loadingSubject.next(true);
|
||||||
this.projectService.SearchProjects(limit, offset).then(res => {
|
this.projectService.SearchProjects(limit, offset).then(res => {
|
||||||
this.ownedProjectList = res.toObject().resultList;
|
this.ownedProjectList = res.toObject().resultList;
|
||||||
this.totalResult = res.toObject().totalResult;
|
this.totalResult = res.toObject().totalResult;
|
||||||
this.dataSource.data = this.ownedProjectList;
|
this.dataSource.data = this.ownedProjectList;
|
||||||
this.loadingSubject.next(false);
|
this.loadingSubject.next(false);
|
||||||
console.log(this.ownedProjectList);
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
this.toast.showError(error.message);
|
this.toast.showError(error.message);
|
@@ -3,14 +3,13 @@ import { RouterModule, Routes } from '@angular/router';
|
|||||||
import { AuthGuard } from 'src/app/guards/auth.guard';
|
import { AuthGuard } from 'src/app/guards/auth.guard';
|
||||||
import { RoleGuard } from 'src/app/guards/role.guard';
|
import { RoleGuard } from 'src/app/guards/role.guard';
|
||||||
|
|
||||||
import { GrantedProjectDetailComponent } from './granted-project-detail/granted-project-detail.component';
|
|
||||||
import { OwnedProjectDetailComponent } from './owned-project-detail/owned-project-detail.component';
|
import { OwnedProjectDetailComponent } from './owned-project-detail/owned-project-detail.component';
|
||||||
import { ProjectsComponent } from './projects.component';
|
import { OwnedProjectsComponent } from './owned-projects.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: ProjectsComponent,
|
component: OwnedProjectsComponent,
|
||||||
data: { animation: 'HomePage' },
|
data: { animation: 'HomePage' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -21,11 +20,6 @@ const routes: Routes = [
|
|||||||
roles: ['project.write'],
|
roles: ['project.write'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: ':id/grant/:grantId',
|
|
||||||
component: GrantedProjectDetailComponent,
|
|
||||||
data: { animation: 'HomePage' },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: ':id',
|
path: ':id',
|
||||||
component: OwnedProjectDetailComponent,
|
component: OwnedProjectDetailComponent,
|
||||||
@@ -33,7 +27,7 @@ const routes: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':projectid/members',
|
path: ':projectid/members',
|
||||||
loadChildren: () => import('./project-members/project-members.module').then(m => m.ProjectMembersModule),
|
loadChildren: () => import('../../modules/project-members/project-members.module').then(m => m.ProjectMembersModule),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':projectid/apps',
|
path: ':projectid/apps',
|
||||||
@@ -56,4 +50,4 @@ const routes: Routes = [
|
|||||||
imports: [RouterModule.forChild(routes)],
|
imports: [RouterModule.forChild(routes)],
|
||||||
exports: [RouterModule],
|
exports: [RouterModule],
|
||||||
})
|
})
|
||||||
export class ProjectsRoutingModule { }
|
export class OwnedProjectsRoutingModule { }
|
@@ -0,0 +1,7 @@
|
|||||||
|
<div class="max-width-container">
|
||||||
|
<h1>{{ 'PROJECT.PAGES.LIST' | translate }}</h1>
|
||||||
|
<p class="sub">{{ 'PROJECT.PAGES.LISTDESCRIPTION' | translate }}</p>
|
||||||
|
|
||||||
|
<h2>Owned Projects</h2>
|
||||||
|
<app-owned-project-list></app-owned-project-list>
|
||||||
|
</div>
|
@@ -0,0 +1,13 @@
|
|||||||
|
h1 {
|
||||||
|
font-family: ailerons;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub {
|
||||||
|
color: #81868a;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.max-width-container {
|
||||||
|
padding-bottom: 3rem;
|
||||||
|
}
|
@@ -3,11 +3,11 @@ import { ActivatedRoute } from '@angular/router';
|
|||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-projects',
|
selector: 'app-owned-projects',
|
||||||
templateUrl: './projects.component.html',
|
templateUrl: './owned-projects.component.html',
|
||||||
styleUrls: ['./projects.component.scss'],
|
styleUrls: ['./owned-projects.component.scss'],
|
||||||
})
|
})
|
||||||
export class ProjectsComponent implements OnInit, OnDestroy {
|
export class OwnedProjectsComponent implements OnInit, OnDestroy {
|
||||||
// public projectId: string = '';
|
// public projectId: string = '';
|
||||||
// public grantId: string = '';
|
// public grantId: string = '';
|
||||||
private sub: Subscription = new Subscription();
|
private sub: Subscription = new Subscription();
|
@@ -1,6 +1,6 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||||
@@ -20,55 +20,45 @@ import { MatTableModule } from '@angular/material/table';
|
|||||||
import { MatTabsModule } from '@angular/material/tabs';
|
import { MatTabsModule } from '@angular/material/tabs';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
import { HttpLoaderFactory } from 'src/app/app.module';
|
|
||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
|
||||||
import { CardModule } from 'src/app/modules/card/card.module';
|
|
||||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
|
||||||
import { SearchUserAutocompleteModule } from 'src/app/modules/search-user-autocomplete/search-user-autocomplete.module';
|
|
||||||
import { PipesModule } from 'src/app/pipes/pipes.module';
|
|
||||||
|
|
||||||
|
import { HttpLoaderFactory } from '../../app.module';
|
||||||
|
import { HasRoleModule } from '../../directives/has-role/has-role.module';
|
||||||
|
import { CardModule } from '../../modules/card/card.module';
|
||||||
import { ChangesModule } from '../../modules/changes/changes.module';
|
import { ChangesModule } from '../../modules/changes/changes.module';
|
||||||
|
import { MetaLayoutModule } from '../../modules/meta-layout/meta-layout.module';
|
||||||
|
import { ProjectContributorsModule } from '../../modules/project-contributors/project-contributors.module';
|
||||||
import { ProjectRolesModule } from '../../modules/project-roles/project-roles.module';
|
import { ProjectRolesModule } from '../../modules/project-roles/project-roles.module';
|
||||||
|
import { SearchUserAutocompleteModule } from '../../modules/search-user-autocomplete/search-user-autocomplete.module';
|
||||||
|
import { PipesModule } from '../../pipes/pipes.module';
|
||||||
import { OrgContributorsModule } from '../orgs/org-contributors/org-contributors.module';
|
import { OrgContributorsModule } from '../orgs/org-contributors/org-contributors.module';
|
||||||
import { UserListModule } from '../user-list/user-list.module';
|
import { UserListModule } from '../user-list/user-list.module';
|
||||||
import { GrantedProjectDetailComponent } from './granted-project-detail/granted-project-detail.component';
|
|
||||||
import { GrantedProjectGridComponent } from './granted-project-grid/granted-project-grid.component';
|
|
||||||
import { GrantedProjectListComponent } from './granted-project-list/granted-project-list.component';
|
|
||||||
import { OwnedProjectDetailComponent } from './owned-project-detail/owned-project-detail.component';
|
import { OwnedProjectDetailComponent } from './owned-project-detail/owned-project-detail.component';
|
||||||
import { OwnedProjectGridComponent } from './owned-project-grid/owned-project-grid.component';
|
import { OwnedProjectGridComponent } from './owned-project-grid/owned-project-grid.component';
|
||||||
import { OwnedProjectListComponent } from './owned-project-list/owned-project-list.component';
|
import { OwnedProjectListComponent } from './owned-project-list/owned-project-list.component';
|
||||||
|
import { OwnedProjectsRoutingModule } from './owned-projects-routing.module';
|
||||||
|
import { OwnedProjectsComponent } from './owned-projects.component';
|
||||||
import { ProjectApplicationGridComponent } from './project-application-grid/project-application-grid.component';
|
import { ProjectApplicationGridComponent } from './project-application-grid/project-application-grid.component';
|
||||||
import { ProjectApplicationsComponent } from './project-applications/project-applications.component';
|
import { ProjectApplicationsComponent } from './project-applications/project-applications.component';
|
||||||
import { ProjectContributorsComponent } from './project-contributors/project-contributors.component';
|
|
||||||
import {
|
import {
|
||||||
ProjectGrantMembersCreateDialogComponent,
|
ProjectGrantMembersCreateDialogComponent,
|
||||||
} from './project-grant-members-create-dialog/project-grant-members-create-dialog.component';
|
} from './project-grant-members-create-dialog/project-grant-members-create-dialog.component';
|
||||||
import { ProjectGrantMembersComponent } from './project-grant-members/project-grant-members.component';
|
|
||||||
import { ProjectGrantsComponent } from './project-grants/project-grants.component';
|
import { ProjectGrantsComponent } from './project-grants/project-grants.component';
|
||||||
import { ProjectsRoutingModule } from './projects-routing.module';
|
|
||||||
import { ProjectsComponent } from './projects.component';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
GrantedProjectListComponent,
|
OwnedProjectsComponent,
|
||||||
GrantedProjectGridComponent,
|
|
||||||
GrantedProjectDetailComponent,
|
|
||||||
|
|
||||||
OwnedProjectListComponent,
|
OwnedProjectListComponent,
|
||||||
OwnedProjectGridComponent,
|
OwnedProjectGridComponent,
|
||||||
OwnedProjectDetailComponent,
|
OwnedProjectDetailComponent,
|
||||||
|
|
||||||
ProjectApplicationsComponent,
|
|
||||||
ProjectApplicationGridComponent,
|
ProjectApplicationGridComponent,
|
||||||
|
ProjectApplicationsComponent,
|
||||||
ProjectGrantsComponent,
|
ProjectGrantsComponent,
|
||||||
ProjectGrantMembersComponent,
|
|
||||||
ProjectGrantMembersCreateDialogComponent,
|
ProjectGrantMembersCreateDialogComponent,
|
||||||
ProjectContributorsComponent,
|
|
||||||
ProjectsComponent,
|
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
ProjectsRoutingModule,
|
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
OwnedProjectsRoutingModule,
|
||||||
|
ProjectContributorsModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
@@ -106,10 +96,6 @@ import { ProjectsComponent } from './projects.component';
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
entryComponents: [
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
ProjectGrantMembersCreateDialogComponent,
|
|
||||||
],
|
|
||||||
exports: [],
|
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
|
|
||||||
})
|
})
|
||||||
export class ProjectsModule { }
|
export class OwnedProjectsModule { }
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user