mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 21:17:23 +00:00
fix(console): some imperfections, delete memberships from detail, role delete from table, app state (#1551)
* app state, roles, remove memberships, feature detail * chore(deps): bump tslib from 2.0.3 to 2.2.0 in /console (#1549) * fix: pass necessary webauthn data through events (#1541) * fix: pass necessary webauthn data through events (#1544) * docs: update readme (#1460) (#1545) * Update readme * Apply suggestions from code review but features Co-authored-by: Florian Forster <florian@caos.ch> * Update README.md Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Maximilian Panne <maximilian.panne@gmail.com> Co-authored-by: Florian Forster <florian@caos.ch> (cherry picked from commit 5c5b13cf84aca3641ec8fd43036c7ec25479d598) Co-authored-by: mffap <mpa@caos.ch> * chore(deps): bump tslib from 2.0.3 to 2.2.0 in /console Bumps [tslib](https://github.com/Microsoft/tslib) from 2.0.3 to 2.2.0. - [Release notes](https://github.com/Microsoft/tslib/releases) - [Commits](https://github.com/Microsoft/tslib/compare/2.0.3...2.2.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: mffap <mpa@caos.ch> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/language-service from 11.2.0 to 11.2.8 in /console (#1521) * fix: pass necessary webauthn data through events (#1541) * fix: pass necessary webauthn data through events (#1544) * docs: update readme (#1460) (#1545) * Update readme * Apply suggestions from code review but features Co-authored-by: Florian Forster <florian@caos.ch> * Update README.md Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Maximilian Panne <maximilian.panne@gmail.com> Co-authored-by: Florian Forster <florian@caos.ch> (cherry picked from commit 5c5b13cf84aca3641ec8fd43036c7ec25479d598) Co-authored-by: mffap <mpa@caos.ch> * chore(deps-dev): bump @angular/language-service in /console Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 11.2.0 to 11.2.8. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/11.2.8/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/11.2.8/packages/language-service) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: mffap <mpa@caos.ch> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular-devkit/build-angular from 0.1102.1 to 0.1102.7 in /console (#1520) * fix: pass necessary webauthn data through events (#1541) * fix: pass necessary webauthn data through events (#1544) * docs: update readme (#1460) (#1545) * Update readme * Apply suggestions from code review but features Co-authored-by: Florian Forster <florian@caos.ch> * Update README.md Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Maximilian Panne <maximilian.panne@gmail.com> Co-authored-by: Florian Forster <florian@caos.ch> (cherry picked from commit 5c5b13cf84aca3641ec8fd43036c7ec25479d598) Co-authored-by: mffap <mpa@caos.ch> * chore(deps-dev): bump @angular-devkit/build-angular in /console Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 0.1102.1 to 0.1102.7. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/commits) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: mffap <mpa@caos.ch> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump karma from 6.1.1 to 6.3.2 in /console (#1519) * fix: pass necessary webauthn data through events (#1541) * fix: pass necessary webauthn data through events (#1544) * docs: update readme (#1460) (#1545) * Update readme * Apply suggestions from code review but features Co-authored-by: Florian Forster <florian@caos.ch> * Update README.md Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Maximilian Panne <maximilian.panne@gmail.com> Co-authored-by: Florian Forster <florian@caos.ch> (cherry picked from commit 5c5b13cf84aca3641ec8fd43036c7ec25479d598) Co-authored-by: mffap <mpa@caos.ch> * chore(deps-dev): bump karma from 6.1.1 to 6.3.2 in /console Bumps [karma](https://github.com/karma-runner/karma) from 6.1.1 to 6.3.2. - [Release notes](https://github.com/karma-runner/karma/releases) - [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md) - [Commits](https://github.com/karma-runner/karma/compare/v6.1.1...v6.3.2) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: mffap <mpa@caos.ch> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump google-protobuf from 3.13.0 to 3.15.7 in /console (#1518) * fix: pass necessary webauthn data through events (#1541) * fix: pass necessary webauthn data through events (#1544) * docs: update readme (#1460) (#1545) * Update readme * Apply suggestions from code review but features Co-authored-by: Florian Forster <florian@caos.ch> * Update README.md Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Maximilian Panne <maximilian.panne@gmail.com> Co-authored-by: Florian Forster <florian@caos.ch> (cherry picked from commit 5c5b13cf84aca3641ec8fd43036c7ec25479d598) Co-authored-by: mffap <mpa@caos.ch> * chore(deps): bump google-protobuf from 3.13.0 to 3.15.7 in /console Bumps [google-protobuf](https://github.com/protocolbuffers/protobuf) from 3.13.0 to 3.15.7. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/master/generate_changelog.py) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.13.0...v3.15.7) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: mffap <mpa@caos.ch> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/cli from 11.2.0 to 11.2.7 in /console (#1517) * fix: pass necessary webauthn data through events (#1541) * fix: pass necessary webauthn data through events (#1544) * docs: update readme (#1460) (#1545) * Update readme * Apply suggestions from code review but features Co-authored-by: Florian Forster <florian@caos.ch> * Update README.md Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Maximilian Panne <maximilian.panne@gmail.com> Co-authored-by: Florian Forster <florian@caos.ch> (cherry picked from commit 5c5b13cf84aca3641ec8fd43036c7ec25479d598) Co-authored-by: mffap <mpa@caos.ch> * chore(deps-dev): bump @angular/cli from 11.2.0 to 11.2.7 in /console Bumps [@angular/cli](https://github.com/angular/angular-cli) from 11.2.0 to 11.2.7. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/compare/v11.2.0...v11.2.7) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: mffap <mpa@caos.ch> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> * chore(deps-dev): bump @types/node from 14.14.28 to 14.14.37 in /console (#1489) * fix: pass necessary webauthn data through events (#1541) * fix: pass necessary webauthn data through events (#1544) * docs: update readme (#1460) (#1545) * Update readme * Apply suggestions from code review but features Co-authored-by: Florian Forster <florian@caos.ch> * Update README.md Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Maximilian Panne <maximilian.panne@gmail.com> Co-authored-by: Florian Forster <florian@caos.ch> (cherry picked from commit 5c5b13cf84aca3641ec8fd43036c7ec25479d598) Co-authored-by: mffap <mpa@caos.ch> * chore(deps-dev): bump @types/node from 14.14.28 to 14.14.37 in /console Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.28 to 14.14.37. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: mffap <mpa@caos.ch> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: mffap <mpa@caos.ch>
This commit is contained in:
parent
3487a7a713
commit
e9a457ddf5
2041
console/package-lock.json
generated
2041
console/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@
|
||||
"cors": "^2.8.5",
|
||||
"file-saver": "^2.0.5",
|
||||
"google-proto-files": "^2.4.0",
|
||||
"google-protobuf": "^3.13.0",
|
||||
"google-protobuf": "^3.15.7",
|
||||
"grpc": "^1.24.5",
|
||||
"grpc-web": "^1.2.1",
|
||||
"libphonenumber-js": "^1.9.13",
|
||||
@ -40,22 +40,22 @@
|
||||
"ngx-quicklink": "^0.2.6",
|
||||
"rxjs": "~6.6.3",
|
||||
"ts-protoc-gen": "^0.14.0",
|
||||
"tslib": "^2.0.0",
|
||||
"tslib": "^2.2.0",
|
||||
"uuid": "^8.3.2",
|
||||
"zone.js": "~0.11.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "~11.2.0",
|
||||
"@angular-devkit/build-angular": "~0.1102.1",
|
||||
"@angular/cli": "~11.2.7",
|
||||
"@angular-devkit/build-angular": "~0.1102.7",
|
||||
"@angular/compiler-cli": "~11.0.0",
|
||||
"@types/jasmine": "~3.6.3",
|
||||
"@angular/language-service": "~11.2.0",
|
||||
"@angular/language-service": "~11.2.8",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "^14.14.28",
|
||||
"@types/node": "^14.14.37",
|
||||
"codelyzer": "^6.0.0",
|
||||
"jasmine-core": "~3.6.0",
|
||||
"jasmine-spec-reporter": "~6.0.0",
|
||||
"karma": "~6.1.1",
|
||||
"karma": "~6.3.2",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
|
@ -31,17 +31,6 @@
|
||||
dayelement.dates[j] | timestampToDate | localizedDate: 'HH:mm'
|
||||
}}</span>
|
||||
</span>
|
||||
<!-- <span *ngIf="histindex === 0 && i === 0 && j === 0">
|
||||
<span>current file</span>
|
||||
<span class="block">{{
|
||||
dayelement.dates[j] | timestampToDate | localizedDate: 'HH:mm'
|
||||
}}</span>
|
||||
</span> -->
|
||||
|
||||
<!-- <button mat-icon-button disabled>
|
||||
<mat-icon class="icon red" color="warn">error_outline
|
||||
</mat-icon>
|
||||
</button> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -129,14 +129,15 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.end-container {
|
||||
font-size: 12px;
|
||||
color: var(--grey);
|
||||
font-size: 14px;
|
||||
margin: 1rem 0;
|
||||
color: var(--grey);
|
||||
}
|
||||
.end-container {
|
||||
font-size: 12px;
|
||||
color: var(--grey);
|
||||
font-size: 14px;
|
||||
margin: 1rem 0 1rem 0;
|
||||
display: block;
|
||||
color: var(--grey);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<app-detail-layout [backRouterLink]="[ serviceType === FeatureServiceType.ADMIN ? '/iam/policies' : '/org']"
|
||||
[title]="'FEATURES.TITLE' | translate" [description]="'FEATURES.DESCRIPTION' | translate">
|
||||
[title]="'ZITADEL ' +features?.tier.name + ' ' + ('FEATURES.TITLE' | translate)" [description]="'FEATURES.DESCRIPTION' | translate">
|
||||
<p class="default" *ngIf="isDefault"> {{'POLICY.DEFAULTLABEL' | translate}}</p>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['iam.features.delete']">
|
||||
@ -14,7 +14,7 @@
|
||||
<div class="row">
|
||||
<span class="left-desc">{{'FEATURES.DATA.AUDITLOGRETENTION' | translate}}</span>
|
||||
<span class="fill-space"></span>
|
||||
<span>{{features.auditLogRetention | json }}</span>
|
||||
<span>{{features.auditLogRetention | timestampToRetention }} {{'FEATURES.RETENTIONHOURS' | translate}}</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="left-desc">{{'FEATURES.DATA.LOGINPOLICYUSERNAMELOGIN' | translate}}</span>
|
||||
|
@ -10,6 +10,9 @@ import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||
import {
|
||||
TimestampToRetentionPipeModule,
|
||||
} from 'src/app/pipes/timestamp-to-retention-pipe/timestamp-to-retention-pipe.module';
|
||||
|
||||
import { InfoSectionModule } from '../info-section/info-section.module';
|
||||
import { FeaturesRoutingModule } from './features-routing.module';
|
||||
@ -34,6 +37,7 @@ import { FeaturesComponent } from './features.component';
|
||||
InfoSectionModule,
|
||||
TranslateModule,
|
||||
DetailLayoutModule,
|
||||
TimestampToRetentionPipeModule,
|
||||
],
|
||||
exports: [
|
||||
FeaturesComponent,
|
||||
|
@ -1,13 +1,7 @@
|
||||
<app-refresh-table *ngIf="projectId" (refreshed)="refreshPage()" [dataSize]="dataSource?.totalResult"
|
||||
[emitRefreshOnPreviousRoutes]="['/projects/'+projectId+'/roles/create']" [selection]="selection"
|
||||
[loading]="dataSource?.loading$ | async" [timestamp]="dataSource?.viewTimestamp">
|
||||
<ng-template appHasRole [appHasRole]="['project.role.delete', 'project.role.delete:' + projectId]" actions>
|
||||
<button color="warn" class="icon-button" [disabled]="disabled"
|
||||
matTooltip="{{'PROJECT.ROLE.DELETE' | translate}}" (click)="deleteSelectedRoles()" mat-icon-button
|
||||
*ngIf="selection.hasValue() && actionsVisible">
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['project.role.write:' + projectId, 'project.role.write']" actions>
|
||||
<a *ngIf="actionsVisible" [disabled]="disabled" [routerLink]="[ '/projects', projectId, 'roles', 'create']"
|
||||
color="primary" mat-raised-button>
|
||||
@ -57,6 +51,18 @@
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions" stickyEnd>
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let role">
|
||||
<button
|
||||
[disabled]="disabled || (['project.role.delete', 'project.role.delete:' + projectId] | hasRole | async) == false"
|
||||
mat-icon-button color="warn" matTooltip="{{'ACTIONS.DELETE' | translate}}"
|
||||
(click)="deleteRole(role)">
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr class="highlight" mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
|
@ -41,3 +41,18 @@
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
tr {
|
||||
outline: none;
|
||||
|
||||
button {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
button {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ export class ProjectRolesComponent implements AfterViewInit, OnInit {
|
||||
@Output() public changedSelection: EventEmitter<Array<Role.AsObject>> = new EventEmitter();
|
||||
|
||||
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
|
||||
public displayedColumns: string[] = ['select', 'key', 'displayname', 'group', 'creationDate'];
|
||||
public displayedColumns: string[] = ['select', 'key', 'displayname', 'group', 'creationDate', 'actions'];
|
||||
|
||||
constructor(private mgmtService: ManagementService, private toast: ToastService, private dialog: MatDialog) {
|
||||
this.dataSource = new ProjectRolesDataSource(this.mgmtService);
|
||||
@ -76,25 +76,16 @@ export class ProjectRolesComponent implements AfterViewInit, OnInit {
|
||||
this.dataSource.rolesSubject.value.forEach((row: Role.AsObject) => this.selection.select(row));
|
||||
}
|
||||
|
||||
public deleteSelectedRoles(): Promise<any> {
|
||||
const oldState = this.dataSource.rolesSubject.value;
|
||||
const indexes = this.selection.selected.map(sel => {
|
||||
return oldState.findIndex(iter => iter.key === sel.key);
|
||||
});
|
||||
public deleteRole(role: Role.AsObject): Promise<any> {
|
||||
const index = this.dataSource.rolesSubject.value.findIndex(iter => iter.key === role.key);
|
||||
|
||||
return Promise.all(this.selection.selected.map(role => {
|
||||
return this.mgmtService.removeProjectRole(this.projectId, role.key);
|
||||
})).then(() => {
|
||||
return this.mgmtService.removeProjectRole(this.projectId, role.key).then(() => {
|
||||
this.toast.showInfo('PROJECT.TOAST.ROLEREMOVED', true);
|
||||
indexes.forEach(index => {
|
||||
if (index > -1) {
|
||||
oldState.splice(index, 1);
|
||||
this.dataSource.rolesSubject.next(this.dataSource.rolesSubject.value);
|
||||
}
|
||||
});
|
||||
this.selection.clear();
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
|
||||
if (index > -1) {
|
||||
this.dataSource.rolesSubject.value.splice(index, 1);
|
||||
this.dataSource.rolesSubject.next(this.dataSource.rolesSubject.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,6 @@
|
||||
font-size: 16px;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<i matTooltip="verified" *ngIf="domain.isVerified" class="verified las la-check-circle"></i>
|
||||
<i matTooltip="primary" *ngIf="domain.isPrimary" class="primary las la-star"></i>
|
||||
<a *ngIf="!domain.isPrimary && (canwrite$ | async)" class="primaryset"
|
||||
<a *ngIf="domain.isVerified && !domain.isPrimary && (canwrite$ | async)" class="primaryset"
|
||||
(click)="setPrimary(domain)">{{'ORG.DOMAINS.SETPRIMARY' | translate}}</a>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
|
@ -12,14 +12,26 @@
|
||||
</div>
|
||||
<ng-container *ngIf="isZitadel === false">
|
||||
<ng-template appHasRole [appHasRole]="['project.app.write:'+projectId, 'project.app.write']">
|
||||
|
||||
<button *ngIf="!editState" matTooltip="{{'ACTIONS.EDIT' | translate}}" mat-icon-button
|
||||
(click)="editState = !editState" aria-label="edit app name">
|
||||
(click)="editState = !editState" aria-label="edit app name">
|
||||
<i class="las la-edit"></i>
|
||||
</button>
|
||||
<button *ngIf="editState" (click)="saveApp()" [disabled]="appNameForm.invalid || name?.disabled"
|
||||
mat-icon-button>
|
||||
<i class="las la-save"></i>
|
||||
</button>
|
||||
|
||||
<button class="state-button" mat-stroked-button color="warn"
|
||||
*ngIf="app.state !== undefined && app?.state !== AppState.APP_STATE_INACTIVE"
|
||||
(click)="changeState(AppState.APP_STATE_INACTIVE)">
|
||||
{{'ACTIONS.DEACTIVATE' | translate}}
|
||||
</button>
|
||||
<button class="state-button" mat-stroked-button
|
||||
*ngIf="app.state !== undefined && app?.state !== AppState.APP_STATE_ACTIVE"
|
||||
(click)="changeState(AppState.APP_STATE_ACTIVE)">
|
||||
{{'ACTIONS.REACTIVATE' | translate}}
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['project.app.delete:'+projectId, 'project.app.delete']">
|
||||
@ -38,17 +50,6 @@
|
||||
|
||||
<form *ngIf="app && editState" [formGroup]="appNameForm">
|
||||
<div class="name-content">
|
||||
<mat-button-toggle-group formControlName="state" class="toggle" (change)="changeState($event)">
|
||||
<mat-button-toggle [value]="AppState.APP_STATE_INACTIVE"
|
||||
matTooltip="{{ 'ACTIONS.DEACTIVATE' | translate}}">
|
||||
{{'APP.PAGES.DETAIL.STATE.'+AppState.APP_STATE_INACTIVE | translate}}
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="AppState.APPSTATE_ACTIVE"
|
||||
matTooltip="{{ 'ACTIONS.REACTIVATE' | translate}}">
|
||||
{{'APP.PAGES.DETAIL.STATE.'+AppState.APP_STATE_ACTIVE | translate}}
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
|
||||
<cnsl-form-field class="name-field">
|
||||
<cnsl-label>{{ 'APP.NAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="name" />
|
||||
|
@ -37,6 +37,10 @@
|
||||
font-size: 14px;
|
||||
color: rgb(201, 51, 71);
|
||||
}
|
||||
|
||||
.state-button {
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.err-container {
|
||||
|
@ -3,7 +3,6 @@ import { Location } from '@angular/common';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatButtonToggleChange } from '@angular/material/button-toggle';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
@ -382,15 +381,17 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
public changeState(event: MatButtonToggleChange): void {
|
||||
if (event.value === AppState.APP_STATE_ACTIVE) {
|
||||
public changeState(state: AppState): void {
|
||||
if (state === AppState.APP_STATE_ACTIVE) {
|
||||
this.mgmtService.reactivateApp(this.projectId, this.app.id).then(() => {
|
||||
this.app.state = state;
|
||||
this.toast.showInfo('APP.TOAST.REACTIVATED', true);
|
||||
}).catch((error: any) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
} else if (event.value === AppState.APP_STATE_INACTIVE) {
|
||||
} else if (state === AppState.APP_STATE_INACTIVE) {
|
||||
this.mgmtService.deactivateApp(this.projectId, this.app.id).then(() => {
|
||||
this.app.state = state;
|
||||
this.toast.showInfo('APP.TOAST.DEACTIVATED', true);
|
||||
}).catch((error: any) => {
|
||||
this.toast.showError(error);
|
||||
|
@ -29,12 +29,12 @@
|
||||
|
||||
<ng-container matColumnDef="externalUserDisplayName">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'USER.EXTERNALIDP.USERDISPLAYNAME' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let idp"> {{idp?.externalUserDisplayName}} </td>
|
||||
<td mat-cell *matCellDef="let idp"> {{idp?.providedUserName}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="externalUserId">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'USER.EXTERNALIDP.EXTERNALUSERID' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let idp"> {{idp?.externalUserId}} </td>
|
||||
<td mat-cell *matCellDef="let idp"> {{idp?.providedUserId}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions" stickyEnd>
|
||||
|
@ -27,10 +27,13 @@
|
||||
<ng-container matColumnDef="memberType">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'USER.MEMBERSHIPS.TYPE' | translate }} </th>
|
||||
<td class="pointer" mat-cell *matCellDef="let member">
|
||||
<span *ngIf="member.orgId && !member.projectGrantId && !member.projectId"> {{'USER.MEMBERSHIPS.TYPES.ORG' | translate }}</span>
|
||||
<span *ngIf="member.projectId && !member.projectGrantId"> {{'USER.MEMBERSHIPS.TYPES.PROJECT' | translate }}</span>
|
||||
<span *ngIf="member.projectId && member.projectGrantId"> {{'USER.MEMBERSHIPS.TYPES.GRANTEDPROJECT' | translate }}</span>
|
||||
</td>
|
||||
<span *ngIf="member.orgId && !member.projectGrantId && !member.projectId">
|
||||
{{'USER.MEMBERSHIPS.TYPES.ORG' | translate }}</span>
|
||||
<span *ngIf="member.projectId && !member.projectGrantId"> {{'USER.MEMBERSHIPS.TYPES.PROJECT' |
|
||||
translate }}</span>
|
||||
<span *ngIf="member.projectId && member.projectGrantId">
|
||||
{{'USER.MEMBERSHIPS.TYPES.GRANTEDPROJECT' | translate }}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="displayName">
|
||||
@ -59,6 +62,17 @@
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions" stickyEnd>
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let member">
|
||||
<button [disabled]="member.projectId && member.projectGrantId ? (['project.grant.member.delete:' + member.projectGrantId, 'project.grant.member.delete'] | hasRole | async) == false : member.projectId ? (['project.member.delete:' + member.projectGrantId, 'project.member.delete'] | hasRole | async) == false : member.orgId ? (['org.member.delete:' + member.orgId, 'org.member.delete'] | hasRole | async) == false : (['iam.member.delete'] | hasRole | async) == false"
|
||||
mat-icon-button color="warn" matTooltip="{{'ACTIONS.REMOVE' | translate}}"
|
||||
(click)="removeMembership(member)">
|
||||
<i class="las la-minus-circle"></i>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr class="highlight" mat-row *matRowDef="let row; columns: displayedColumns;">
|
||||
</tr>
|
||||
|
@ -34,3 +34,19 @@
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
tr {
|
||||
outline: none;
|
||||
|
||||
button {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
button {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ export class MembershipDetailComponent implements AfterViewInit {
|
||||
public memberRoleOptions: string[] = [];
|
||||
|
||||
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
|
||||
public displayedColumns: string[] = ['select', 'memberType', 'displayName', 'creationDate', 'changeDate', 'roles'];
|
||||
public displayedColumns: string[] = ['select', 'memberType', 'displayName', 'creationDate', 'changeDate', 'roles', 'actions'];
|
||||
|
||||
public loading: boolean = false;
|
||||
public memberships!: Membership.AsObject[];
|
||||
@ -203,6 +203,27 @@ export class MembershipDetailComponent implements AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
public removeMembership(membership: Membership.AsObject): void {
|
||||
let prom;
|
||||
|
||||
if (membership.projectId && membership.projectGrantId && membership.userId) {
|
||||
prom = this.mgmtService.removeProjectGrantMember(membership.projectId, membership.projectGrantId, membership.userId);
|
||||
} else if (membership.projectId && membership.userId) {
|
||||
prom = this.mgmtService.removeProjectMember(membership.projectId, membership.userId);
|
||||
} else if (membership.orgId && membership.userId) {
|
||||
prom = this.mgmtService.removeOrgMember(membership.userId);
|
||||
} else if (membership.userId) {
|
||||
prom = this.adminService.removeIAMMember(membership.userId);
|
||||
}
|
||||
|
||||
if (prom) {
|
||||
prom.then(() => {
|
||||
this.toast.showInfo('PROJECT.TOAST.MEMBERREMOVED', true);
|
||||
this.refreshPage();
|
||||
}).catch(error => this.toast.showError(error));
|
||||
}
|
||||
}
|
||||
|
||||
public refreshPage(): void {
|
||||
this.selection.clear();
|
||||
this.dataSource.loadMemberships(this.user.id, this.paginator.pageIndex, this.paginator.pageSize);
|
||||
|
@ -12,6 +12,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
|
||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
||||
|
||||
@ -43,6 +44,7 @@ const routes: Routes = [
|
||||
HasRoleModule,
|
||||
MatIconModule,
|
||||
MatButtonModule,
|
||||
HasRolePipeModule,
|
||||
RefreshTableModule,
|
||||
MatTooltipModule,
|
||||
],
|
||||
|
@ -10,8 +10,8 @@
|
||||
[ngStyle]="{'z-index': 100 - i}">
|
||||
<div class="membership-avatar" [ngStyle]="{'background-color': getColor(membership)}">
|
||||
<i *ngIf="membership.orgId" class="las la-archway"></i>
|
||||
<i *ngIf="membership.projectId && !membership.grantId" class="icon las la-layer-group"></i>
|
||||
<i *ngIf="membership.projectId && membership.grantId" class="icon las la-layer-group"></i>
|
||||
<i *ngIf="membership.projectId && !membership.projectGrantId" class="icon las la-layer-group"></i>
|
||||
<i *ngIf="membership.projectId && membership.projectGrantId" class="icon las la-layer-group"></i>
|
||||
|
||||
<span>{{membership.displayName}}</span>
|
||||
</div>
|
||||
@ -25,6 +25,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<button [disabled]="disabled" class="add-img" (click)="addMember()" mat-icon-button
|
||||
matTooltip="{{'ACTIONS.ADD' | translate}}" aria-label="add membership">
|
||||
<mat-icon>add</mat-icon>
|
||||
|
@ -15,11 +15,11 @@
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['user.write$', 'user.write:'+user?.id]">
|
||||
<button class="state-button" mat-stroked-button color="warn"
|
||||
*ngIf="user?.state === UserState.USER_STATE_ACTIVE"
|
||||
*ngIf="user?.state !== UserState.USER_STATE_INACTIVE"
|
||||
(click)="changeState(UserState.USER_STATE_INACTIVE)">{{'USER.PAGES.DEACTIVATE' |
|
||||
translate}}</button>
|
||||
<button class="state-button" mat-stroked-button color="warn"
|
||||
*ngIf="user?.state === UserState.USER_STATE_INACTIVE"
|
||||
*ngIf="user?.state !== UserState.USER_STATE_ACTIVE"
|
||||
(click)="changeState(UserState.USER_STATE_ACTIVE)">{{'USER.PAGES.REACTIVATE' | translate}}</button>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
@ -48,10 +48,10 @@
|
||||
|
||||
<ng-container matColumnDef="displayName">
|
||||
<th mat-header-cell *matHeaderCellDef
|
||||
[ngClass]="{'search-active': this.userSearchKey == UserListSearchKey.USERSEARCHKEY_DISPLAY_NAME}">
|
||||
[ngClass]="{'search-active': this.userSearchKey == UserListSearchKey.DISPLAY_NAME}">
|
||||
{{ 'USER.PROFILE.DISPLAYNAME' | translate }}
|
||||
<template [ngTemplateOutlet]="templateRef"
|
||||
[ngTemplateOutletContext]="{key: UserListSearchKey.USERSEARCHKEY_DISPLAY_NAME}"></template>
|
||||
[ngTemplateOutletContext]="{key: UserListSearchKey.DISPLAY_NAME}"></template>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let user" [routerLink]="user.id ? ['/users', user.id ]: null">
|
||||
{{user.human?.profile?.displayName}}
|
||||
|
@ -0,0 +1,18 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { TimestampToRetentionPipe } from './timestamp-to-retention.pipe';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
TimestampToRetentionPipe,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
],
|
||||
exports: [
|
||||
TimestampToRetentionPipe,
|
||||
],
|
||||
})
|
||||
export class TimestampToRetentionPipeModule { }
|
@ -0,0 +1,25 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { Duration } from 'google-protobuf/google/protobuf/duration_pb';
|
||||
|
||||
@Pipe({
|
||||
name: 'timestampToRetention',
|
||||
})
|
||||
export class TimestampToRetentionPipe implements PipeTransform {
|
||||
|
||||
transform(value?: Duration.AsObject, ...args: unknown[]): unknown {
|
||||
if (value) {
|
||||
return this.retentionFromTimestamp(value);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
private retentionFromTimestamp(date: Duration.AsObject): any {
|
||||
if (date?.seconds !== undefined && date?.nanos !== undefined) {
|
||||
const ms = (date.seconds * 1000 + date.nanos / 1000 / 1000);
|
||||
const mins = ms / 1000 / 60;
|
||||
return mins / 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -173,6 +173,7 @@
|
||||
"DEACTIVATE":"Deaktivieren",
|
||||
"ACTIVATE":"Aktivieren",
|
||||
"FILTER": {
|
||||
"0":"Nach displayName filtern",
|
||||
"1":"Nach Username filtern",
|
||||
"2":"Nach Vornamen filtern",
|
||||
"3":"Nach Nachnamen filtern",
|
||||
@ -588,7 +589,8 @@
|
||||
"2":"Annuliert",
|
||||
"3":"Besitzstandswahrend"
|
||||
},
|
||||
"NOTAVAILABLE":"Feature {{value}} ist auf Ihrer organisation nicht freigeschaltet!"
|
||||
"NOTAVAILABLE":"Feature {{value}} ist auf Ihrer organisation nicht freigeschaltet!",
|
||||
"RETENTIONHOURS":"Stunden"
|
||||
},
|
||||
"POLICY": {
|
||||
"TITLE":"Richtlinen entdecken",
|
||||
|
@ -173,6 +173,7 @@
|
||||
"DEACTIVATE":"Deactivate",
|
||||
"ACTIVATE":"Activate",
|
||||
"FILTER": {
|
||||
"0":"Filter for DisplayName",
|
||||
"1":"Filter for Username",
|
||||
"2":"filter for Firstname",
|
||||
"3":"filter for Lastname",
|
||||
@ -586,7 +587,8 @@
|
||||
"2":"Cancelled",
|
||||
"3":"Grandfathered"
|
||||
},
|
||||
"NOTAVAILABLE":"Feature {{value}} is missing on your organization."
|
||||
"NOTAVAILABLE":"Feature {{value}} is missing on your organization.",
|
||||
"RETENTIONHOURS":"Hours"
|
||||
},
|
||||
"POLICY": {
|
||||
"TITLE":"Explore Policies",
|
||||
|
Loading…
x
Reference in New Issue
Block a user