several fixes and improvements

- Add projector logo/headerimage
- Fixed opening multiselect action menu for users.
- Used defined toolbar color for multiselect mode.
- (server) Added check for 'request.data._mutable = True' to edit user
  profile as normal user.
This commit is contained in:
Emanuel Schütze 2019-02-18 11:26:47 +01:00
parent cc45525678
commit c9c4566c08
7 changed files with 76 additions and 61 deletions

View File

@ -35,5 +35,5 @@
}
mat-toolbar.multi-select {
background-color: #757575;
background-color: #757575 !important;
}

View File

@ -1,7 +1,9 @@
<div id="container" [osResized]="resizeSubject" [ngStyle]="containerStyle" #container>
<div id="projector" [ngStyle]="projectorStyle">
<div id="header" [ngStyle]="headerFooterStyle" *ngIf="enableHeaderAndFooter">
<!-- TODO: Logo <img *ngIf="enableLogo" id="logo"> -->
<!-- projector logo -->
<os-logo *ngIf="enableLogo" inputAction="logo_projector_main" class="projector-logo-main"> </os-logo>
<div *ngIf="enableTitle" id="eventdata">
<div
*ngIf="eventName"

View File

@ -21,12 +21,12 @@
margin-bottom: 20px;
z-index: 1;
#logo {
.projector-logo-main {
height: 50px;
padding-left: 50px;
padding-top: 10px;
height: 50px;
margin-right: 25px;
float: left;
display: flex;
}
#eventdata {

View File

@ -157,20 +157,33 @@ export class ProjectorComponent extends BaseComponent implements OnDestroy {
super(titleService, translate);
// Get all important config variables.
// enable header/footer
this.configService
.get<boolean>('projector_enable_header_footer')
.subscribe(val => (this.enableHeaderAndFooter = val));
this.configService.get<boolean>('projector_enable_title').subscribe(val => (this.enableTitle = val));
// projector colors
this.configService
.get<string>('projector_header_fontcolor')
.subscribe(val => (this.headerFooterStyle.color = val));
this.configService
.get<string>('projector_header_backgroundcolor')
.subscribe(val => (this.headerFooterStyle['background-color'] = val));
this.configService.get<boolean>('projector_enable_logo').subscribe(val => (this.enableLogo = val));
this.configService
.get<string>('projector_background_color')
.subscribe(val => (this.projectorStyle['background-color'] = val));
// projector logo / background-image
this.configService.get<boolean>('projector_enable_logo').subscribe(val => (this.enableLogo = val));
this.configService.get<{ path?: string }>('logo_projector_header').subscribe(val => {
if (val && val.path) {
this.headerFooterStyle['background-image'] = "url('" + val.path + "')";
}
});
// event data
this.configService.get<string>('general_event_name').subscribe(val => (this.eventName = val));
this.configService.get<string>('general_event_description').subscribe(val => (this.eventDescription = val));
this.configService.get<string>('general_event_date').subscribe(val => (this.eventDate = val));

View File

@ -47,7 +47,6 @@
*ngIf="user"
(keydown)="onKeyDown($event)"
>
<!-- <h3 translate>Personal Data</h3> -->
<div *ngIf="isAllowed('seeName')">
<!-- Title -->
<mat-form-field
@ -106,7 +105,7 @@
</mat-form-field>
<!-- Gender -->
<mat-form-field class="form25 force-min-with" *ngIf="user.gender || editUser">
<mat-form-field class="form25 force-min-with" *ngIf="user.gender || (editUser && isAllowed('manage'))">
<mat-select placeholder="{{ 'Gender' | translate }}" formControlName="gender">
<mat-option>-</mat-option>
<mat-option *ngFor="let gender of genderList" [value]="gender">{{ gender | translate }}</mat-option>

View File

@ -124,72 +124,71 @@
<mat-icon>cloud_upload</mat-icon>
<span translate>Import</span><span>&nbsp;...</span>
</button>
</div>
<div *ngIf="isMultiSelect">
<button mat-menu-item (click)="selectAll()">
<mat-icon>done_all</mat-icon>
<span translate>Select all</span>
</button>
<div *ngIf="isMultiSelect">
<button mat-menu-item (click)="selectAll()">
<mat-icon>done_all</mat-icon>
<span translate>Select all</span>
<button mat-menu-item (click)="deselectAll()">
<mat-icon>clear</mat-icon>
<span translate>Deselect all</span>
</button>
<div *osPerms="'users.can_manage'">
<mat-divider></mat-divider>
<button mat-menu-item (click)="setGroupSelected()">
<mat-icon>people</mat-icon>
<span translate>Add/remove groups ...</span>
</button>
<button mat-menu-item (click)="deselectAll()">
<mat-icon>clear</mat-icon>
<span translate>Deselect all</span>
<div *ngIf="presenceViewConfigured">
<button mat-menu-item *osPerms="'users.can_manage'" routerLink="presence">
<mat-icon>transfer_within_a_station</mat-icon>
<span translate>Presence</span>
</button>
</div>
<button mat-menu-item *osPerms="'users.can_manage'" routerLink="import">
<mat-icon>save_alt</mat-icon>
<span translate>Import</span><span>&nbsp;...</span>
</button>
<div *osPerms="'users.can_manage'">
<mat-divider></mat-divider>
<button mat-menu-item (click)="setGroupSelected()">
<mat-icon>people</mat-icon>
<span translate>Add/remove groups ...</span>
<button mat-menu-item (click)="setActiveSelected()">
<mat-icon>block</mat-icon>
<span translate>Enable/disable account ...</span>
</button>
<div *ngIf="presenceViewConfigured">
<button mat-menu-item *osPerms="'users.can_manage'" routerLink="presence">
<mat-icon>transfer_within_a_station</mat-icon>
<span translate>Presence</span>
</button>
</div>
<button mat-menu-item *osPerms="'users.can_manage'" routerLink="import">
<mat-icon>save_alt</mat-icon>
<span translate>Import</span><span>&nbsp;...</span>
<button mat-menu-item (click)="setPresentSelected()">
<mat-icon>check_box</mat-icon>
<span translate>Set presence ...</span>
</button>
<div *osPerms="'users.can_manage'">
<mat-divider></mat-divider>
<button mat-menu-item (click)="setCommitteeSelected()">
<mat-icon>account_balance</mat-icon>
<span translate>Set committee ...</span>
</button>
<button mat-menu-item (click)="setActiveSelected()">
<mat-icon>block</mat-icon>
<span translate>Enable/disable account ...</span>
</button>
<mat-divider></mat-divider>
<button mat-menu-item (click)="setPresentSelected()">
<mat-icon>check_box</mat-icon>
<span translate>Set presence ...</span>
</button>
<button mat-menu-item (click)="sendInvitationEmailSelected()">
<mat-icon>mail</mat-icon>
<span translate>Send invitation email</span>
</button>
<button mat-menu-item (click)="setCommitteeSelected()">
<mat-icon>account_balance</mat-icon>
<span translate>Set committee ...</span>
</button>
<mat-divider></mat-divider>
<button mat-menu-item (click)="sendInvitationEmailSelected()">
<mat-icon>mail</mat-icon>
<span translate>Send invitation email</span>
</button>
<button mat-menu-item (click)="resetPasswordsSelected()">
<mat-icon>vpn_key</mat-icon>
<span translate>Generate new passwords</span>
</button>
<mat-divider></mat-divider>
<button mat-menu-item class="red-warning-text" (click)="deleteSelected()">
<mat-icon>delete</mat-icon>
<span translate>Delete</span>
</button>
</div>
<button mat-menu-item (click)="resetPasswordsSelected()">
<mat-icon>vpn_key</mat-icon>
<span translate>Generate new passwords</span>
</button>
<mat-divider></mat-divider>
<button mat-menu-item class="red-warning-text" (click)="deleteSelected()">
<mat-icon>delete</mat-icon>
<span translate>Delete</span>
</button>
</div>
</div>
</div>

View File

@ -16,6 +16,7 @@ from django.contrib.sites.shortcuts import get_current_site
from django.core import mail
from django.core.exceptions import ValidationError as DjangoValidationError
from django.db import transaction
from django.http.request import QueryDict
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
@ -114,7 +115,8 @@ class UserViewSet(ModelViewSet):
self.permission_denied(request)
# This is a hack to make request.data mutable. Otherwise fields can not be deleted.
request.data._mutable = True
if isinstance(request.data, QueryDict):
request.data._mutable = True
# Remove fields that the user is not allowed to change.
# The list() is required because we want to use del inside the loop.
for key in list(request.data.keys()):