mirror of
https://github.com/zitadel/zitadel.git
synced 2025-03-01 00:07:22 +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:
parent
ee73dc07dd
commit
0a488eb1fb
@ -32,7 +32,12 @@
|
||||
"styles": [
|
||||
"src/styles.scss"
|
||||
],
|
||||
"scripts": []
|
||||
"scripts": [],
|
||||
"allowedCommonJsDependencies": [
|
||||
"@angular/common/locales/de",
|
||||
"src/app/proto/generated/*.js",
|
||||
"src/app/proto/generated/**/*.js"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
|
@ -10,9 +10,17 @@ const routes: Routes = [
|
||||
loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule),
|
||||
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',
|
||||
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],
|
||||
data: {
|
||||
roles: ['project.read'],
|
||||
|
@ -1,110 +1,116 @@
|
||||
<mat-toolbar class="root-header">
|
||||
<button aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
|
||||
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
|
||||
</button>
|
||||
<a *ngIf="(isHandset$ | async) == false" class="title ailerons" [routerLink]="['/']">
|
||||
<img class="logo" *ngIf="componentCssClass == 'dark-theme'; else lighttheme"
|
||||
src="../assets/images/zitadel-logo-oneline-darkdesign.svg" />
|
||||
<ng-template #lighttheme>
|
||||
<img class="logo" src="../assets/images/zitadel-logo-oneline-lightdesign.svg" />
|
||||
</ng-template>
|
||||
</a>
|
||||
<ng-container *ngIf="(authService.user | async) || {} as user">
|
||||
<mat-toolbar class="root-header">
|
||||
<button aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
|
||||
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
|
||||
</button>
|
||||
<a *ngIf="(isHandset$ | async) == false" class="title ailerons" [routerLink]="['/']">
|
||||
<img class="logo" *ngIf="componentCssClass == 'dark-theme'; else lighttheme"
|
||||
src="../assets/images/zitadel-logo-oneline-darkdesign.svg" />
|
||||
<ng-template #lighttheme>
|
||||
<img class="logo" src="../assets/images/zitadel-logo-oneline-lightdesign.svg" />
|
||||
</ng-template>
|
||||
</a>
|
||||
|
||||
<button (click)="loadOrgs()" *ngIf="profile?.id && org" mat-button
|
||||
[matMenuTriggerFor]="menu">{{org?.name ? org.name : 'NO NAME'}}
|
||||
<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 (click)="loadOrgs()" *ngIf="profile?.id && org" mat-button
|
||||
[matMenuTriggerFor]="menu">{{org?.name ? org.name : 'NO NAME'}}
|
||||
<mat-icon>
|
||||
arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['iam.write']">
|
||||
<button mat-menu-item [routerLink]="[ '/org/create' ]">
|
||||
<mat-icon class="avatar">add</mat-icon>
|
||||
{{'MENU.NEWORG' | translate}}
|
||||
<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>
|
||||
</ng-template>
|
||||
</mat-menu>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['iam.write']">
|
||||
<div matTooltip="IAM Administrator" class="iamreadwrite"></div>
|
||||
</ng-template>
|
||||
<ng-template appHasRole [appHasRole]="['iam.write']">
|
||||
<button mat-menu-item [routerLink]="[ '/org/create' ]">
|
||||
<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 class="avatar-wrapper dontcloseonclick" (click)="showAccount = !showAccount">
|
||||
<div class="avatar-circle dontcloseonclick" [ngClass]="{'active': showAccount}">
|
||||
<i *ngIf="componentCssClass == 'dark-theme'; else lighttheme"
|
||||
class="avatar dontcloseonclick las la-user-circle"></i>
|
||||
|
||||
<ng-template #lighttheme>
|
||||
<i class="avatar las la-user-circle"></i>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div (clickOutside)="closeAccountCard()" class="icon-container">
|
||||
<app-avatar *ngIf="user && (user.displayName || (user.firstName && user.lastName))"
|
||||
class="avatar dontcloseonclick" (click)="showAccount = !showAccount" [active]="showAccount"
|
||||
[name]="user.displayName ? user.displayName : (user.firstName + ' '+ user.lastName)" [size]="38">
|
||||
</app-avatar>
|
||||
<app-accounts-card @accounts class="a_card mat-elevation-z5" *ngIf="showAccount"
|
||||
(close)="showAccount = false" [profile]="profile" [iamuser]="iamreadwrite">
|
||||
</app-accounts-card>
|
||||
</div>
|
||||
<app-accounts-card @accounts class="a_card mat-elevation-z5" *ngIf="showAccount" (close)="showAccount = false"
|
||||
[profile]="profile" [iamuser]="iamreadwrite">
|
||||
</app-accounts-card>
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
</mat-toolbar>
|
||||
|
||||
<mat-drawer-container *ngIf="(authService.user | async) || {} as user" class="main-container">
|
||||
<mat-drawer #drawer class="side" [mode]="(isHandset$ | async) ? 'over' : 'side'" [opened]="!(isHandset$ | async)">
|
||||
<div class="side-column">
|
||||
<div class="list">
|
||||
<a *ngIf="authService.authenticationChanged | async" class="nav-item" [routerLinkActive]="['active']"
|
||||
[routerLinkActiveOptions]="{ exact: true }" [routerLink]="['/user/me']">
|
||||
<i class="icon las la-user-circle"></i>
|
||||
<span class="label">{{ 'MENU.PERSONAL_INFO' | translate }}</span>
|
||||
</a>
|
||||
<mat-drawer-container class="main-container">
|
||||
<mat-drawer #drawer class="side" [mode]="(isHandset$ | async) ? 'over' : 'side'"
|
||||
[opened]="!(isHandset$ | async)">
|
||||
<div class="side-column">
|
||||
<div class="list">
|
||||
<a *ngIf="authService.authenticationChanged | async" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }"
|
||||
[routerLink]="['/user/me']">
|
||||
<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']">
|
||||
<i class="icon las la-gem"></i>
|
||||
<span class="label">{{'MENU.IAM' | translate}}</span>
|
||||
</a>
|
||||
<div class="divider"><span></span></div>
|
||||
|
||||
<a *ngIf="showOrgSection" class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/org']">
|
||||
<i class="icon las la-archway"></i>
|
||||
<span class="label">{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}</span>
|
||||
</a>
|
||||
<a *ngIf="iamreadwrite" class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/iam']">
|
||||
<i class="icon las la-gem"></i>
|
||||
<span class="label">{{'MENU.IAM' | 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="showOrgSection" class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/org']">
|
||||
<i class="icon las la-archway"></i>
|
||||
<span class="label">{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}</span>
|
||||
</a>
|
||||
|
||||
<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>
|
||||
<div class="divider"><span></span></div>
|
||||
|
||||
<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>
|
||||
<a class="nav-item" (click)="authService.signout()">
|
||||
<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">
|
||||
<!-- <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">Impressum</a>
|
||||
</div> -->
|
||||
</div>
|
||||
</mat-drawer>
|
||||
<mat-drawer-content class="content">
|
||||
<div class="router" [@routeAnimations]="prepareRoute(outlet)">
|
||||
<router-outlet #outlet="outlet"></router-outlet>
|
||||
</div>
|
||||
</mat-drawer-content>
|
||||
</mat-drawer-container>
|
||||
</div>
|
||||
</mat-drawer>
|
||||
<mat-drawer-content class="content">
|
||||
<ng-template appHasRole [appHasRole]="['iam.write']">
|
||||
<div class="admin-line" matTooltip="IAM Administrator">
|
||||
<span>{{'MENU.IAMADMIN' | translate}}</span>
|
||||
</div>
|
||||
</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 {
|
||||
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 {
|
||||
display: flex;
|
||||
@ -51,44 +44,16 @@
|
||||
font-family: 'ailerons', sans-serif;
|
||||
}
|
||||
|
||||
.avatar-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.avatar {
|
||||
display: block;
|
||||
margin: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.avatar-circle {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
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;
|
||||
}
|
||||
}
|
||||
.name {
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.a_card {
|
||||
position: absolute;
|
||||
@ -99,6 +64,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.admin-line {
|
||||
font-size: 12px;
|
||||
padding: 4px 2rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.main-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -239,4 +210,11 @@
|
||||
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.authService.user.subscribe(userprofile => {
|
||||
console.log(userprofile);
|
||||
this.profile = userprofile;
|
||||
const lang = userprofile.preferredLanguage.match(/en|de/) ? userprofile.preferredLanguage : 'en';
|
||||
this.translate.use(lang);
|
||||
|
@ -25,6 +25,7 @@ import { AppComponent } from './app.component';
|
||||
import { HasRoleModule } from './directives/has-role/has-role.module';
|
||||
import { OutsideClickModule } from './directives/outside-click/outside-click.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 { AuthUserService } from './services/auth-user.service';
|
||||
import { AuthService } from './services/auth.service';
|
||||
@ -102,6 +103,7 @@ export const authConfig: AuthConfig = {
|
||||
MatToolbarModule,
|
||||
MatMenuModule,
|
||||
MatSnackBarModule,
|
||||
AvatarModule,
|
||||
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
|
||||
],
|
||||
providers: [
|
||||
|
@ -15,7 +15,6 @@ export class HasRoleDirective {
|
||||
this.viewContainerRef.clear();
|
||||
this.viewContainerRef.createEmbeddedView(this.templateRef);
|
||||
} else if (this.hasView) {
|
||||
console.log('User blocked!', roles, isAllowed);
|
||||
this.viewContainerRef.clear();
|
||||
this.hasView = false;
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ export class AuthGuard implements CanActivate {
|
||||
state: RouterStateSnapshot,
|
||||
): Observable<boolean> | Promise<boolean> | boolean {
|
||||
if (!this.auth.authenticated) {
|
||||
console.log('authenticate');
|
||||
return this.auth.authenticate();
|
||||
}
|
||||
return this.auth.authenticated;
|
||||
|
@ -1,12 +1,15 @@
|
||||
<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-email">{{profile?.userName}}</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">
|
||||
<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)">
|
||||
<i class="small-avatar las la-user-circle"></i>
|
||||
|
||||
@ -29,5 +32,5 @@
|
||||
</a>
|
||||
</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>
|
@ -10,10 +10,6 @@
|
||||
padding: 1rem 0;
|
||||
|
||||
.avatar {
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
border-radius: 50%;
|
||||
line-height: 80px;
|
||||
font-size: 80px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
@ -30,9 +26,6 @@
|
||||
|
||||
.iamuser {
|
||||
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 {
|
||||
|
@ -60,7 +60,7 @@ export class AccountsCardComponent implements OnInit {
|
||||
}
|
||||
|
||||
public logout(): void {
|
||||
this.router.navigate(['/']);
|
||||
this.authService.signout();
|
||||
this.close.emit();
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { OutsideClickModule } from 'src/app/directives/outside-click/outside-click.module';
|
||||
|
||||
import { AvatarModule } from '../avatar/avatar.module';
|
||||
import { AccountsCardComponent } from './accounts-card.component';
|
||||
|
||||
@NgModule({
|
||||
@ -18,6 +19,7 @@ import { AccountsCardComponent } from './accounts-card.component';
|
||||
MatButtonModule,
|
||||
MatProgressBarModule,
|
||||
OutsideClickModule,
|
||||
AvatarModule,
|
||||
TranslateModule,
|
||||
],
|
||||
exports: [
|
||||
|
@ -42,14 +42,12 @@ export class MemberCreateDialogComponent {
|
||||
} else if (this.creationType === CreationType.PROJECT_OWNED) {
|
||||
this.projectService.GetProjectMemberRoles().then(resp => {
|
||||
this.memberRoleOptions = resp.toObject().rolesList;
|
||||
console.log(this.memberRoleOptions);
|
||||
}).catch(error => {
|
||||
toastService.showError(error.message);
|
||||
});
|
||||
} else if (this.creationType === CreationType.IAM) {
|
||||
this.adminService.GetIamMemberRoles().then(resp => {
|
||||
this.memberRoleOptions = resp.toObject().rolesList;
|
||||
console.log(this.memberRoleOptions);
|
||||
}).catch(error => {
|
||||
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 {
|
||||
max-height: 540px;
|
||||
max-height: 60vh;
|
||||
overflow-y: scroll;
|
||||
|
||||
.item {
|
||||
box-sizing: border-box;
|
||||
height: 50px;
|
||||
padding: .5rem;
|
||||
margin: .25rem 0;
|
||||
border-radius: .5rem;
|
||||
|
@ -20,6 +20,7 @@ export class ChangesComponent implements OnInit {
|
||||
@Input() public id: string = '';
|
||||
@Input() public sortDirectionAsc: boolean = true;
|
||||
public errorMessage: string = '';
|
||||
public bottom: boolean = false;
|
||||
|
||||
// Source data
|
||||
private _done: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||
@ -93,36 +94,36 @@ export class ChangesComponent implements OnInit {
|
||||
private mapAndUpdate(col: Promise<Changes>): any {
|
||||
if (this._done.value || this._loading.value) { return; }
|
||||
|
||||
// loading
|
||||
this._loading.next(true);
|
||||
|
||||
// Map snapshot with doc ref (needed for cursor)
|
||||
return from(col).pipe(
|
||||
tap((res: Changes) => {
|
||||
console.log('more changes');
|
||||
let values = res.toObject().changesList;
|
||||
// If prepending, reverse the batch order
|
||||
values = false ? values.reverse() : values;
|
||||
if (!this.bottom) {
|
||||
// loading
|
||||
this._loading.next(true);
|
||||
|
||||
// update source with new values, done loading
|
||||
this._data.next(values);
|
||||
console.log(values);
|
||||
return from(col).pipe(
|
||||
tap((res: Changes) => {
|
||||
let values = res.toObject().changesList;
|
||||
// If prepending, reverse the batch order
|
||||
values = false ? values.reverse() : values;
|
||||
|
||||
// console.log(values);
|
||||
this._loading.next(false);
|
||||
// update source with new values, done loading
|
||||
this._data.next(values);
|
||||
|
||||
// no more values, mark done
|
||||
if (!values.length) {
|
||||
this._done.next(true);
|
||||
}
|
||||
}),
|
||||
catchError(err => {
|
||||
console.error(err);
|
||||
this._loading.next(false);
|
||||
this.errorMessage = err.message;
|
||||
return of([]);
|
||||
}),
|
||||
take(1),
|
||||
).subscribe();
|
||||
this._loading.next(false);
|
||||
|
||||
// no more values, mark done
|
||||
if (!values.length) {
|
||||
this._done.next(true);
|
||||
}
|
||||
}),
|
||||
catchError(err => {
|
||||
console.error(err);
|
||||
this._loading.next(false);
|
||||
this.errorMessage = decodeURI(err.message);
|
||||
this.bottom = true;
|
||||
return of([]);
|
||||
}),
|
||||
take(1),
|
||||
).subscribe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
<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>
|
||||
<ng-content class="meta-content" select="metainfo"></ng-content>
|
||||
</div>
|
||||
|
@ -15,7 +15,6 @@
|
||||
}
|
||||
|
||||
.meta {
|
||||
overflow-y: hidden;
|
||||
position: relative;
|
||||
flex: 1 0 300px;
|
||||
background: linear-gradient(to bottom right, #4072b410 20%,transparent 50%);
|
||||
|
@ -7,7 +7,11 @@
|
||||
<ng-container *ngFor="let member of membersSubject | async">
|
||||
<div (click)="showDetail()" class="avatar-circle"
|
||||
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>
|
||||
</ng-container>
|
||||
</ng-container>
|
@ -15,10 +15,7 @@ import {
|
||||
import { ProjectService } from 'src/app/services/project.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
import {
|
||||
CreationType,
|
||||
MemberCreateDialogComponent,
|
||||
} from '../../../modules/add-member-dialog/member-create-dialog.component';
|
||||
import { CreationType, MemberCreateDialogComponent } from '../../modules/add-member-dialog/member-create-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-project-contributors',
|
||||
@ -43,7 +40,6 @@ export class ProjectContributorsComponent implements OnInit {
|
||||
private router: Router) { }
|
||||
|
||||
public ngOnInit(): void {
|
||||
console.log('project grant members');
|
||||
const promise: Promise<ProjectMemberSearchResponse> | undefined =
|
||||
this.projectType === ProjectType.PROJECTTYPE_OWNED ?
|
||||
this.projectService.SearchProjectMembers(this.project.projectId, 100, 0) :
|
||||
@ -59,7 +55,6 @@ export class ProjectContributorsComponent implements OnInit {
|
||||
catchError(() => of([])),
|
||||
finalize(() => this.loadingSubject.next(false)),
|
||||
).subscribe(members => {
|
||||
console.log(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(
|
||||
map(resp => {
|
||||
this.totalResult = resp.toObject().totalResult;
|
||||
console.log(this.totalResult);
|
||||
return resp.toObject().resultList;
|
||||
}),
|
||||
catchError(() => of([])),
|
@ -33,7 +33,6 @@ export class ProjectMembersComponent implements AfterViewInit {
|
||||
this.route.params.subscribe(params => {
|
||||
this.projectService.GetProjectById(params.projectid).then(project => {
|
||||
this.project = project.toObject();
|
||||
console.log(this.project);
|
||||
this.dataSource = new ProjectMembersDataSource(this.projectService);
|
||||
this.dataSource.loadMembers(this.project, this.projectType, 0, 25, 'asc');
|
||||
});
|
@ -31,7 +31,6 @@ export class ProjectRolesDataSource extends DataSource<ProjectRole.AsObject> {
|
||||
catchError(() => of([])),
|
||||
finalize(() => this.loadingSubject.next(false)),
|
||||
).subscribe(roles => {
|
||||
console.log(roles);
|
||||
this.rolesSubject.next(roles);
|
||||
});
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ export class SearchProjectAutocompleteComponent {
|
||||
}),
|
||||
// finalize(() => this.isLoading = false),
|
||||
).subscribe((projects) => {
|
||||
console.log(projects.toObject().resultList);
|
||||
this.isLoading = false;
|
||||
this.filteredProjects = projects.toObject().resultList;
|
||||
});
|
||||
|
@ -48,11 +48,9 @@ export class SearchRolesAutocompleteComponent {
|
||||
return from(this.projectService.SearchProjectRoles(this.projectId, 10, 0, [query]));
|
||||
}),
|
||||
).subscribe((roles) => {
|
||||
console.log(roles.toObject().resultList);
|
||||
this.isLoading = false;
|
||||
this.filteredRoles = roles.toObject().resultList;
|
||||
}, error => {
|
||||
console.log(error);
|
||||
this.isLoading = false;
|
||||
});
|
||||
}
|
||||
|
@ -99,8 +99,6 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
||||
this.oidcApp.responseTypesList = this.responseTypesList?.value;
|
||||
this.oidcApp.authMethodType = this.authMethodType?.value;
|
||||
|
||||
console.log(this.oidcApp);
|
||||
|
||||
this.projectService
|
||||
.CreateOIDCApp(this.oidcApp)
|
||||
.then((data: Application) => {
|
||||
@ -119,7 +117,6 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
console.log('The dialog was closed');
|
||||
this.router.navigate(['projects', this.projectId, 'apps', app.id]);
|
||||
});
|
||||
} else {
|
||||
|
@ -118,7 +118,6 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
this.projectService.GetApplicationById(projectid, id).then(app => {
|
||||
this.app = app.toObject();
|
||||
this.appNameForm.patchValue(this.app);
|
||||
console.log(this.grpcService.clientid, this.app.oidcConfig?.clientId);
|
||||
|
||||
if (this.app.state !== AppState.APPSTATE_ACTIVE) {
|
||||
this.appNameForm.controls['name'].disable();
|
||||
@ -220,8 +219,6 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
this.app.oidcConfig.redirectUrisList = this.redirectUrisList;
|
||||
this.app.oidcConfig.postLogoutRedirectUrisList = this.postLogoutRedirectUrisList;
|
||||
|
||||
console.log(this.app.oidcConfig);
|
||||
|
||||
this.projectService
|
||||
.UpdateOIDCAppConfig(this.projectId, this.app.id, this.app.oidcConfig)
|
||||
.then((data: OIDCConfig) => {
|
||||
@ -235,9 +232,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public regenerateOIDCClientSecret(): void {
|
||||
console.log(this.app.id, this.projectId);
|
||||
this.projectService.RegenerateOIDCClientSecret(this.app.id, this.projectId).then((data: OIDCConfig) => {
|
||||
console.log(data.toObject());
|
||||
this.toast.showInfo('OIDC Secret Regenerated');
|
||||
this.dialog.open(AppSecretDialogComponent, {
|
||||
data: {
|
||||
|
@ -86,7 +86,6 @@ export class GrantedProjectDetailComponent implements OnInit, OnDestroy {
|
||||
if (this.projectId && this.grantId) {
|
||||
this.projectService.GetGrantedProjectByID(this.projectId, this.grantId).then(proj => {
|
||||
this.project = proj.toObject();
|
||||
console.log(this.project);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error.message);
|
||||
});
|
@ -90,7 +90,6 @@ export class GrantedProjectListComponent implements OnInit, OnDestroy {
|
||||
this.totalResult = res.toObject().totalResult;
|
||||
this.dataSource.data = this.grantedProjectList;
|
||||
this.loadingSubject.next(false);
|
||||
console.log(this.grantedProjectList);
|
||||
}).catch(error => {
|
||||
console.error(error);
|
||||
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>
|
||||
<p class="sub">{{ 'PROJECT.PAGES.LISTDESCRIPTION' | translate }}</p>
|
||||
|
||||
<h2>Owned Projects</h2>
|
||||
<app-owned-project-list></app-owned-project-list>
|
||||
|
||||
<h2>Granted Projects</h2>
|
||||
<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([])),
|
||||
finalize(() => this.loadingSubject.next(false)),
|
||||
).subscribe(members => {
|
||||
console.log(members);
|
||||
this.membersSubject.next(members);
|
||||
});
|
||||
|
@ -101,7 +101,6 @@ export class ProjectGrantMembersComponent implements AfterViewInit, OnInit {
|
||||
|
||||
dialogRef.afterClosed().subscribe(resp => {
|
||||
if (resp) {
|
||||
console.log(resp);
|
||||
const users: User.AsObject[] = resp.users;
|
||||
const roles: string[] = resp.roles;
|
||||
|
@ -4,7 +4,6 @@
|
||||
<ng-template #lighttheme>
|
||||
<img src="../assets/images/zitadel-logo-oneline-lightdesign.svg" />
|
||||
</ng-template>
|
||||
<p>{{'HOME.DESCRIPTION' | translate}}</p>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
@ -53,8 +53,8 @@
|
||||
}
|
||||
|
||||
img {
|
||||
height: 90px;
|
||||
margin-bottom: 2rem;
|
||||
height: 60px;
|
||||
align-self: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,14 +73,6 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: border-color .1s;
|
||||
|
||||
&:hover {
|
||||
i {
|
||||
color: #fe11e280;
|
||||
}
|
||||
// border-width: 2px;
|
||||
border-color: #fe11e270;
|
||||
}
|
||||
|
||||
.top {
|
||||
padding: 1rem 2rem;
|
||||
|
@ -7,7 +7,11 @@
|
||||
<ng-container *ngFor="let member of membersSubject | async">
|
||||
<div (click)="showDetail()" class="avatar-circle"
|
||||
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>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
@ -53,7 +53,6 @@ export class IamContributorsComponent implements OnInit {
|
||||
catchError(() => of([])),
|
||||
finalize(() => this.loadingSubject.next(false)),
|
||||
).subscribe(members => {
|
||||
console.log(members);
|
||||
this.membersSubject.next(members);
|
||||
});
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
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 { IamContributorsComponent } from './iam-contributors.component';
|
||||
@ -30,6 +31,7 @@ import { IamContributorsComponent } from './iam-contributors.component';
|
||||
MatPaginatorModule,
|
||||
MatIconModule,
|
||||
RouterModule,
|
||||
AvatarModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
|
@ -32,7 +32,6 @@ export class IamMembersDataSource extends DataSource<ProjectMember.AsObject> {
|
||||
from(promise).pipe(
|
||||
map(resp => {
|
||||
this.totalResult = resp.toObject().totalResult;
|
||||
console.log(this.totalResult);
|
||||
return resp.toObject().resultList;
|
||||
}),
|
||||
catchError(() => of([])),
|
||||
|
@ -7,7 +7,11 @@
|
||||
<ng-container *ngFor="let member of membersSubject | async">
|
||||
<div (click)="showDetail()" class="avatar-circle"
|
||||
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>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
@ -54,7 +54,6 @@ export class OrgContributorsComponent implements OnInit {
|
||||
catchError(() => of([])),
|
||||
finalize(() => this.loadingSubject.next(false)),
|
||||
).subscribe(members => {
|
||||
console.log(members);
|
||||
this.membersSubject.next(members);
|
||||
});
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
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 { OrgContributorsComponent } from './org-contributors.component';
|
||||
@ -34,6 +35,7 @@ import { OrgContributorsComponent } from './org-contributors.component';
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
AvatarModule,
|
||||
],
|
||||
exports: [
|
||||
OrgContributorsComponent,
|
||||
|
@ -100,7 +100,6 @@ export class OrgCreateComponent {
|
||||
confirmPassword: ['', [...validators, passwordConfirmValidator]],
|
||||
});
|
||||
}).catch(error => {
|
||||
console.log('no password complexity policy defined!');
|
||||
console.error(error);
|
||||
this.userForm = this.fb.group({
|
||||
userName: ['', [Validators.required]],
|
||||
|
@ -24,7 +24,7 @@
|
||||
<input matInput [(ngModel)]="newDomain" />
|
||||
</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>
|
||||
</button>
|
||||
|
||||
|
@ -52,7 +52,6 @@ export class OrgDetailComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
this.orgService.SearchMyOrgDomains(0, 100).then(result => {
|
||||
console.log(result.toObject().resultList);
|
||||
this.domains = result.toObject().resultList;
|
||||
});
|
||||
}
|
||||
@ -81,7 +80,6 @@ export class OrgDetailComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public removeDomain(domain: string): void {
|
||||
console.log(domain);
|
||||
this.orgService.RemoveMyOrgDomain(domain).then(() => {
|
||||
this.toast.showInfo('Removed');
|
||||
const index = this.domains.findIndex(d => d.domain === domain);
|
||||
|
@ -31,7 +31,6 @@ export class OrgGridComponent {
|
||||
private getData(limit: number, offset: number): void {
|
||||
this.userService.SearchMyProjectOrgs(limit, offset).then(res => {
|
||||
this.orgList = res.toObject().resultList;
|
||||
console.log(this.orgList);
|
||||
}).catch(error => {
|
||||
console.error(error);
|
||||
this.toast.showError(error.message);
|
||||
|
@ -21,7 +21,6 @@ export class OrgMemberRolesAutocompleteComponent {
|
||||
constructor(private orgService: OrgService, private toast: ToastService) {
|
||||
this.orgService.GetOrgMemberRoles().then(resp => {
|
||||
this.allRoles = resp.toObject().rolesList;
|
||||
console.log(this.allRoles);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error.message);
|
||||
});
|
||||
|
@ -31,7 +31,6 @@ export class ProjectMembersDataSource extends DataSource<ProjectMember.AsObject>
|
||||
from(promise).pipe(
|
||||
map(resp => {
|
||||
this.totalResult = resp.toObject().totalResult;
|
||||
console.log(this.totalResult);
|
||||
return resp.toObject().resultList;
|
||||
}),
|
||||
catchError(() => of([])),
|
||||
|
@ -33,7 +33,6 @@ export class OrgMembersComponent implements AfterViewInit {
|
||||
private toast: ToastService) {
|
||||
this.orgService.GetMyOrg().then(org => {
|
||||
this.org = org.toObject();
|
||||
console.log(this.org);
|
||||
this.dataSource = new ProjectMembersDataSource(this.orgService);
|
||||
this.dataSource.loadMembers(0, 25, 'asc');
|
||||
});
|
||||
|
@ -124,7 +124,6 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
||||
break;
|
||||
case PolicyComponentType.IAM_POLICY:
|
||||
this.iamData = data.toObject();
|
||||
console.log(this.iamData);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -236,7 +235,6 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
||||
|
||||
break;
|
||||
case PolicyComponentType.COMPLEXITY:
|
||||
console.log(this.complexityData);
|
||||
this.orgService.CreatePasswordComplexityPolicy(
|
||||
this.complexityData.description,
|
||||
this.complexityData.hasLowercase,
|
||||
@ -252,7 +250,6 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
||||
break;
|
||||
|
||||
case PolicyComponentType.IAM_POLICY:
|
||||
console.log(this.complexityData);
|
||||
const orgId = this.sessionStorage.getItem('organization');
|
||||
if (orgId) {
|
||||
this.adminService.CreateOrgIamPolicy(
|
||||
@ -294,7 +291,6 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
||||
|
||||
break;
|
||||
case PolicyComponentType.COMPLEXITY:
|
||||
console.log(this.complexityData);
|
||||
this.orgService.UpdatePasswordComplexityPolicy(
|
||||
this.complexityData.description,
|
||||
this.complexityData.hasLowercase,
|
||||
@ -310,7 +306,6 @@ export class PasswordPolicyComponent implements OnInit, OnDestroy {
|
||||
break;
|
||||
|
||||
case PolicyComponentType.IAM_POLICY:
|
||||
console.log(this.complexityData);
|
||||
const orgId = this.sessionStorage.getItem('organization');
|
||||
if (orgId) {
|
||||
this.adminService.UpdateOrgIamPolicy(
|
||||
|
@ -85,7 +85,6 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy {
|
||||
if (this.projectId) {
|
||||
this.projectService.GetProjectById(id).then(proj => {
|
||||
this.project = proj.toObject();
|
||||
console.log(this.project);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error.message);
|
||||
});
|
@ -56,7 +56,6 @@ export class OwnedProjectListComponent implements OnInit, OnDestroy {
|
||||
) { }
|
||||
|
||||
public ngOnInit(): void {
|
||||
console.log('asdf');
|
||||
this.getData(10, 0);
|
||||
}
|
||||
|
||||
@ -85,14 +84,12 @@ export class OwnedProjectListComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
private async getData(limit: number, offset: number): Promise<void> {
|
||||
console.log('getprojects');
|
||||
this.loadingSubject.next(true);
|
||||
this.projectService.SearchProjects(limit, offset).then(res => {
|
||||
this.ownedProjectList = res.toObject().resultList;
|
||||
this.totalResult = res.toObject().totalResult;
|
||||
this.dataSource.data = this.ownedProjectList;
|
||||
this.loadingSubject.next(false);
|
||||
console.log(this.ownedProjectList);
|
||||
}).catch(error => {
|
||||
console.error(error);
|
||||
this.toast.showError(error.message);
|
@ -3,14 +3,13 @@ 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 { OwnedProjectDetailComponent } from './owned-project-detail/owned-project-detail.component';
|
||||
import { ProjectsComponent } from './projects.component';
|
||||
import { OwnedProjectsComponent } from './owned-projects.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ProjectsComponent,
|
||||
component: OwnedProjectsComponent,
|
||||
data: { animation: 'HomePage' },
|
||||
},
|
||||
{
|
||||
@ -21,11 +20,6 @@ const routes: Routes = [
|
||||
roles: ['project.write'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: ':id/grant/:grantId',
|
||||
component: GrantedProjectDetailComponent,
|
||||
data: { animation: 'HomePage' },
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
component: OwnedProjectDetailComponent,
|
||||
@ -33,7 +27,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
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',
|
||||
@ -56,4 +50,4 @@ const routes: Routes = [
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
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';
|
||||
|
||||
@Component({
|
||||
selector: 'app-projects',
|
||||
templateUrl: './projects.component.html',
|
||||
styleUrls: ['./projects.component.scss'],
|
||||
selector: 'app-owned-projects',
|
||||
templateUrl: './owned-projects.component.html',
|
||||
styleUrls: ['./owned-projects.component.scss'],
|
||||
})
|
||||
export class ProjectsComponent implements OnInit, OnDestroy {
|
||||
export class OwnedProjectsComponent implements OnInit, OnDestroy {
|
||||
// public projectId: string = '';
|
||||
// public grantId: string = '';
|
||||
private sub: Subscription = new Subscription();
|
@ -1,6 +1,6 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
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 { MatButtonModule } from '@angular/material/button';
|
||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||
@ -20,55 +20,45 @@ 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 '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 { 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 { OwnedProjectDetailComponent } from './owned-project-detail/owned-project-detail.component';
|
||||
import { OwnedProjectGridComponent } from './owned-project-grid/owned-project-grid.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 { ProjectApplicationsComponent } from './project-applications/project-applications.component';
|
||||
import { ProjectContributorsComponent } from './project-contributors/project-contributors.component';
|
||||
import {
|
||||
ProjectGrantMembersCreateDialogComponent,
|
||||
} 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 { ProjectsRoutingModule } from './projects-routing.module';
|
||||
import { ProjectsComponent } from './projects.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
GrantedProjectListComponent,
|
||||
GrantedProjectGridComponent,
|
||||
GrantedProjectDetailComponent,
|
||||
|
||||
OwnedProjectsComponent,
|
||||
OwnedProjectListComponent,
|
||||
OwnedProjectGridComponent,
|
||||
OwnedProjectDetailComponent,
|
||||
|
||||
ProjectApplicationsComponent,
|
||||
ProjectApplicationGridComponent,
|
||||
ProjectApplicationsComponent,
|
||||
ProjectGrantsComponent,
|
||||
ProjectGrantMembersComponent,
|
||||
ProjectGrantMembersCreateDialogComponent,
|
||||
ProjectContributorsComponent,
|
||||
ProjectsComponent,
|
||||
],
|
||||
imports: [
|
||||
ProjectsRoutingModule,
|
||||
CommonModule,
|
||||
OwnedProjectsRoutingModule,
|
||||
ProjectContributorsModule,
|
||||
FormsModule,
|
||||
TranslateModule,
|
||||
ReactiveFormsModule,
|
||||
@ -106,10 +96,6 @@ import { ProjectsComponent } from './projects.component';
|
||||
},
|
||||
}),
|
||||
],
|
||||
entryComponents: [
|
||||
ProjectGrantMembersCreateDialogComponent,
|
||||
],
|
||||
exports: [],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
|
||||
schemas: [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
Loading…
x
Reference in New Issue
Block a user