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:
Max Peintner 2020-06-26 14:15:05 +02:00 committed by GitHub
parent ee73dc07dd
commit 0a488eb1fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
141 changed files with 1133 additions and 742 deletions

View File

@ -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": {

View File

@ -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'],

View File

@ -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>

View File

@ -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;
}

View File

@ -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);

View File

@ -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: [

View File

@ -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;
}

View File

@ -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;

View File

@ -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>

View File

@ -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 {

View File

@ -60,7 +60,7 @@ export class AccountsCardComponent implements OnInit {
}
public logout(): void {
this.router.navigate(['/']);
this.authService.signout();
this.close.emit();
}
}

View File

@ -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: [

View File

@ -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);
});

View 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>

View 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;
}
}

View 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();
});
});

View 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;
}
}
}

View 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 { }

View File

@ -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;

View File

@ -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();
}
}
}

View File

@ -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>

View File

@ -15,7 +15,6 @@
}
.meta {
overflow-y: hidden;
position: relative;
flex: 1 0 300px;
background: linear-gradient(to bottom right, #4072b410 20%,transparent 50%);

View File

@ -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>

View File

@ -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);
});
}

View File

@ -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 { }

View File

@ -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([])),

View File

@ -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');
});

View File

@ -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);
});
}

View File

@ -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;
});

View File

@ -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;
});
}

View File

@ -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 {

View File

@ -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: {

View File

@ -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);
});

View File

@ -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);

View File

@ -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 { }

View File

@ -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>

View File

@ -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();
});
});

View File

@ -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();
}
}

View File

@ -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 { }

View File

@ -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);
});

View File

@ -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;

View File

@ -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">

View File

@ -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;

View File

@ -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>

View File

@ -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);
});
}

View File

@ -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,

View File

@ -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([])),

View File

@ -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>

View File

@ -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);
});
}

View File

@ -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,

View File

@ -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]],

View File

@ -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>

View File

@ -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);

View File

@ -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);

View File

@ -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);
});

View File

@ -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([])),

View File

@ -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');
});

View File

@ -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(

View File

@ -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);
});

View File

@ -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);

View File

@ -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 { }

View File

@ -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>

View File

@ -0,0 +1,13 @@
h1 {
font-family: ailerons;
margin-top: 0;
}
.sub {
color: #81868a;
margin-bottom: 2rem;
}
.max-width-container {
padding-bottom: 3rem;
}

View File

@ -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();

View File

@ -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