add userpref service on frontend

This commit is contained in:
rubikscraft 2022-04-13 17:49:30 +02:00
parent b2320c7592
commit 478e6cc52e
No known key found for this signature in database
GPG key ID: 1463EBE9200A5CD4
6 changed files with 164 additions and 23 deletions

View file

@ -1 +1,6 @@
<h1>Settings</h1>
<p *ngFor="let setting of userPref.live | async">
<span>{{setting.key}}</span>
<span>{{setting.value}}</span>
</p>

View file

@ -1,10 +1,11 @@
import { Component, OnInit } from '@angular/core';
import { UsrPrefService } from 'src/app/services/api/usrpref.service';
@Component({
templateUrl: './settings-general.component.html',
})
export class SettingsGeneralComponent implements OnInit {
constructor() {}
constructor(public userPref: UsrPrefService) {}
ngOnInit(): void {}
}

View file

@ -1,7 +1,7 @@
import { Component } from '@angular/core';
import { DecodedSysPref } from 'picsur-shared/dist/dto/preferences.dto';
import { Observable } from 'rxjs';
import { SysprefService as SysPrefService } from 'src/app/services/api/syspref.service';
import { SysPrefService } from 'src/app/services/api/syspref.service';
@Component({
templateUrl: './settings-syspref.component.html',

View file

@ -6,7 +6,7 @@ import { HasFailed } from 'picsur-shared/dist/types';
import { Subject, throttleTime } from 'rxjs';
import { SysPreferenceFriendlyNames } from 'src/app/i18n/syspref.i18n';
import { SnackBarType } from 'src/app/models/dto/snack-bar-type.dto';
import { SysprefService } from 'src/app/services/api/syspref.service';
import { SysPrefService } from 'src/app/services/api/syspref.service';
import { UtilService } from 'src/app/util/util.service';
@Component({
@ -20,7 +20,7 @@ export class SettingsSysprefOptionComponent implements OnInit {
private updateSubject = new Subject<PrefValueType>();
constructor(
private sysprefService: SysprefService,
private sysprefService: SysPrefService,
private utilService: UtilService
) {}

View file

@ -1,13 +1,16 @@
import { Injectable } from '@angular/core';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import {
GetSysPreferenceResponse,
MultipleSysPreferencesResponse,
UpdateSysPreferenceRequest,
UpdateSysPreferenceResponse
} from 'picsur-shared/dist/dto/api/syspref.dto';
GetPreferenceResponse,
MultiplePreferencesResponse,
UpdatePreferenceRequest,
UpdatePreferenceResponse
} from 'picsur-shared/dist/dto/api/pref.dto';
import { Permission } from 'picsur-shared/dist/dto/permissions.dto';
import { DecodedSysPref, PrefValueType } from 'picsur-shared/dist/dto/preferences.dto';
import {
DecodedPref,
PrefValueType
} from 'picsur-shared/dist/dto/preferences.dto';
import { AsyncFailable, Fail, HasFailed, Map } from 'picsur-shared/dist/types';
import { BehaviorSubject } from 'rxjs';
import { SnackBarType } from 'src/app/models/dto/snack-bar-type.dto';
@ -19,14 +22,12 @@ import { PermissionService } from './permission.service';
@Injectable({
providedIn: 'root',
})
export class SysprefService {
private readonly logger = new Logger('SysprefService');
export class SysPrefService {
private readonly logger = new Logger('SysPrefService');
private hasPermission = false;
private sysprefObservable = new BehaviorSubject<DecodedSysPref[]>(
[]
);
private sysprefObservable = new BehaviorSubject<DecodedPref[]>([]);
public get snapshot() {
return this.sysprefObservable.getValue();
@ -56,12 +57,12 @@ export class SysprefService {
}
}
public async getPreferences(): AsyncFailable<DecodedSysPref[]> {
public async getPreferences(): AsyncFailable<DecodedPref[]> {
if (!this.hasPermission)
return Fail('You do not have permission to edit system preferences');
const response = await this.api.get(
MultipleSysPreferencesResponse,
MultiplePreferencesResponse,
'/api/pref/sys'
);
@ -73,12 +74,12 @@ export class SysprefService {
public async getPreference(
key: string
): AsyncFailable<GetSysPreferenceResponse> {
): AsyncFailable<GetPreferenceResponse> {
if (!this.hasPermission)
return Fail('You do not have permission to edit system preferences');
const response = await this.api.get(
GetSysPreferenceResponse,
GetPreferenceResponse,
`/api/pref/sys/${key}`
);
@ -89,13 +90,13 @@ export class SysprefService {
public async setPreference(
key: string,
value: PrefValueType
): AsyncFailable<UpdateSysPreferenceResponse> {
): AsyncFailable<UpdatePreferenceResponse> {
if (!this.hasPermission)
return Fail('You do not have permission to edit system preferences');
const response = await this.api.post(
UpdateSysPreferenceRequest,
UpdateSysPreferenceResponse,
UpdatePreferenceRequest,
UpdatePreferenceResponse,
`/api/pref/sys/${key}`,
{ value }
);
@ -104,7 +105,7 @@ export class SysprefService {
return response;
}
private updatePrefArray(pref: DecodedSysPref) {
private updatePrefArray(pref: DecodedPref) {
const prefArray = this.snapshot;
// Replace the old pref with the new one
const index = prefArray.findIndex((i) => pref.key === i.key);

View file

@ -0,0 +1,134 @@
import { Injectable } from '@angular/core';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import {
GetPreferenceResponse,
MultiplePreferencesResponse,
UpdatePreferenceRequest,
UpdatePreferenceResponse
} from 'picsur-shared/dist/dto/api/pref.dto';
import { Permission } from 'picsur-shared/dist/dto/permissions.dto';
import {
DecodedPref,
PrefValueType
} from 'picsur-shared/dist/dto/preferences.dto';
import { AsyncFailable, Fail, HasFailed, Map } from 'picsur-shared/dist/types';
import { BehaviorSubject } from 'rxjs';
import { SnackBarType } from 'src/app/models/dto/snack-bar-type.dto';
import { UtilService } from 'src/app/util/util.service';
import { Logger } from '../logger/logger.service';
import { ApiService } from './api.service';
import { PermissionService } from './permission.service';
@Injectable({
providedIn: 'root',
})
export class UsrPrefService {
private readonly logger = new Logger('UsrPrefService');
private hasPermission = false;
private usrprefObservable = new BehaviorSubject<DecodedPref[]>([]);
public get snapshot() {
return this.usrprefObservable.getValue();
}
public get live() {
return this.usrprefObservable.asObservable();
}
constructor(
private api: ApiService,
private permissionsService: PermissionService,
private utilService: UtilService
) {
this.subscribePermissions();
this.init().catch(this.logger.error);
}
private async init() {
const result = await this.getPreferences();
if (HasFailed(result)) {
this.utilService.showSnackBar(
"Couldn't load user preferences",
SnackBarType.Error
);
this.flush();
}
}
public async getPreferences(): AsyncFailable<DecodedPref[]> {
if (!this.hasPermission)
return Fail('You do not have permission to edit user preferences');
const response = await this.api.get(
MultiplePreferencesResponse,
'/api/pref/usr'
);
return Map(response, (pref) => {
this.usrprefObservable.next(pref.preferences);
return pref.preferences;
});
}
public async getPreference(
key: string
): AsyncFailable<GetPreferenceResponse> {
if (!this.hasPermission)
return Fail('You do not have permission to edit user preferences');
const response = await this.api.get(
GetPreferenceResponse,
`/api/pref/usr/${key}`
);
if (!HasFailed(response)) this.updatePrefArray(response);
return response;
}
public async setPreference(
key: string,
value: PrefValueType
): AsyncFailable<UpdatePreferenceResponse> {
if (!this.hasPermission)
return Fail('You do not have permission to edit user preferences');
const response = await this.api.post(
UpdatePreferenceRequest,
UpdatePreferenceResponse,
`/api/pref/usr/${key}`,
{ value }
);
if (!HasFailed(response)) this.updatePrefArray(response);
return response;
}
private updatePrefArray(pref: DecodedPref) {
const prefArray = this.snapshot;
// Replace the old pref with the new one
const index = prefArray.findIndex((i) => pref.key === i.key);
if (index === -1) {
const newArray = [...prefArray, pref];
this.usrprefObservable.next(newArray);
} else {
const newArray = [...prefArray];
newArray[index] = pref;
this.usrprefObservable.next(newArray);
}
}
private flush() {
this.usrprefObservable.next([]);
}
// We want to flush on logout, because the syspreferences can contain sensitive information
@AutoUnsubscribe()
private subscribePermissions() {
return this.permissionsService.live.subscribe((permissions) => {
this.hasPermission = permissions.includes(Permission.Settings);
if (!this.hasPermission) this.flush();
});
}
}