mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-21 00:52:55 +00:00
refactor: replace TSLint with ESLint
This commit is contained in:
committed by
Jovan Krunić
parent
67fb4a43c9
commit
d696215d08
@@ -31,7 +31,6 @@ import {SettingsProvider} from '../settings.provider';
|
||||
templateUrl: 'settings-item.html',
|
||||
})
|
||||
export class SettingsItemComponent {
|
||||
|
||||
/**
|
||||
* If set the setting will be shown as compact view
|
||||
*/
|
||||
@@ -41,6 +40,7 @@ export class SettingsItemComponent {
|
||||
* Flag for workaround for selected 'select option' not updating translation
|
||||
*/
|
||||
isVisible = true;
|
||||
|
||||
/**
|
||||
* The setting to handle
|
||||
*/
|
||||
@@ -52,13 +52,15 @@ export class SettingsItemComponent {
|
||||
* @param translateService TranslateService
|
||||
* @param settingsProvider SettingProvider
|
||||
*/
|
||||
constructor(private readonly alertCtrl: AlertController,
|
||||
private readonly translateService: TranslateService,
|
||||
private readonly settingsProvider: SettingsProvider) {
|
||||
constructor(
|
||||
private readonly alertCtrl: AlertController,
|
||||
private readonly translateService: TranslateService,
|
||||
private readonly settingsProvider: SettingsProvider,
|
||||
) {
|
||||
translateService.onLangChange.subscribe((_event: LangChangeEvent) => {
|
||||
this.isVisible = false;
|
||||
// TODO: Issue #53 check workaround for selected 'select option' not updating translation
|
||||
setTimeout(() => this.isVisible = true);
|
||||
setTimeout(() => (this.isVisible = true));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -81,8 +83,10 @@ export class SettingsItemComponent {
|
||||
* Handles value changes of the setting
|
||||
*/
|
||||
async settingChanged(): Promise<void> {
|
||||
if (typeof this.setting.value !== 'undefined'
|
||||
&& SettingsProvider.validateValue(this.setting, this.setting.value)) {
|
||||
if (
|
||||
typeof this.setting.value !== 'undefined' &&
|
||||
SettingsProvider.validateValue(this.setting, this.setting.value)
|
||||
) {
|
||||
// handle general settings, with special actions
|
||||
switch (this.setting.name) {
|
||||
case 'language':
|
||||
@@ -90,23 +94,25 @@ export class SettingsItemComponent {
|
||||
break;
|
||||
default:
|
||||
}
|
||||
await this.settingsProvider
|
||||
.setSettingValue(this.setting.categories[0],
|
||||
this.setting.name,
|
||||
this.setting.value);
|
||||
await this.settingsProvider.setSettingValue(
|
||||
this.setting.categories[0],
|
||||
this.setting.name,
|
||||
this.setting.value,
|
||||
);
|
||||
} else {
|
||||
// reset setting
|
||||
this.setting.value =
|
||||
await this.settingsProvider
|
||||
.getValue(this.setting.categories[0], this.setting.name) as (SCSettingValue | SCSettingValues);
|
||||
this.setting.value = (await this.settingsProvider.getValue(
|
||||
this.setting.categories[0],
|
||||
this.setting.name,
|
||||
)) as SCSettingValue | SCSettingValues;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping of typeOf for Html usage
|
||||
*/
|
||||
// tslint:disable-next-line:prefer-function-over-method
|
||||
typeOf(val: unknown) {
|
||||
return typeof (val);
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
typeOf(value: unknown) {
|
||||
return typeof value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,80 @@
|
||||
<ion-card *ngIf="setting">
|
||||
<ion-card-header *ngIf="{ name: ('name' | thingTranslate: setting | titlecase), desc: ('description' | thingTranslate: setting | titlecase) } let vals">
|
||||
<ion-card-header
|
||||
*ngIf="
|
||||
{
|
||||
name: ('name' | thingTranslate: setting | titlecase),
|
||||
desc: ('description' | thingTranslate: setting | titlecase)
|
||||
};
|
||||
let vals
|
||||
"
|
||||
>
|
||||
<ion-card-subtitle>
|
||||
{{ vals.name }}
|
||||
<ion-icon *ngIf="compactView" name="information-circle-outline" (click)="presentAlert( vals.name , vals.desc )"></ion-icon>
|
||||
<ion-icon
|
||||
*ngIf="compactView"
|
||||
name="information-circle-outline"
|
||||
(click)="presentAlert(vals.name, vals.desc)"
|
||||
></ion-icon>
|
||||
</ion-card-subtitle>
|
||||
</ion-card-header>
|
||||
<ion-card-content>
|
||||
<ion-note *ngIf="!compactView">{{ 'description' | thingTranslate: setting | titlecase }}</ion-note>
|
||||
<ion-note *ngIf="!compactView">{{
|
||||
'description' | thingTranslate: setting | titlecase
|
||||
}}</ion-note>
|
||||
|
||||
<div [ngSwitch]="setting.inputType" *ngIf="isVisible" >
|
||||
<div [ngSwitch]="setting.inputType" *ngIf="isVisible">
|
||||
<ion-item *ngSwitchCase="'number'">
|
||||
<ion-label></ion-label>
|
||||
<ion-input type='number' [(ngModel)]="setting.value" value={{setting.value}} (ionChange)="settingChanged()"></ion-input>
|
||||
<ion-input
|
||||
type="number"
|
||||
[(ngModel)]="setting.value"
|
||||
value="{{ setting.value }}"
|
||||
(ionChange)="settingChanged()"
|
||||
></ion-input>
|
||||
</ion-item>
|
||||
|
||||
<ion-item *ngSwitchCase="'text'">
|
||||
<ion-label></ion-label>
|
||||
<ion-input type="text" [(ngModel)]="setting.value" value={{setting.value}} (ionChange)="settingChanged()"></ion-input>
|
||||
<ion-input
|
||||
type="text"
|
||||
[(ngModel)]="setting.value"
|
||||
value="{{ setting.value }}"
|
||||
(ionChange)="settingChanged()"
|
||||
></ion-input>
|
||||
</ion-item>
|
||||
|
||||
<ion-item *ngSwitchCase="'password'">
|
||||
<ion-label></ion-label>
|
||||
<ion-input type="password" [(ngModel)]="setting.value" value={{setting.value}} (ionChange)="settingChanged()"></ion-input>
|
||||
<ion-input
|
||||
type="password"
|
||||
[(ngModel)]="setting.value"
|
||||
value="{{ setting.value }}"
|
||||
(ionChange)="settingChanged()"
|
||||
></ion-input>
|
||||
</ion-item>
|
||||
|
||||
<ion-item *ngSwitchCase="'single choice'">
|
||||
<ion-label></ion-label>
|
||||
<!-- if values are boolean show as toggle -->
|
||||
<ion-toggle *ngIf="typeOf(setting.defaultValue) === 'boolean'" [(ngModel)]="setting.value" (ionChange)="settingChanged()"></ion-toggle>
|
||||
<ion-toggle
|
||||
*ngIf="typeOf(setting.defaultValue) === 'boolean'"
|
||||
[(ngModel)]="setting.value"
|
||||
(ionChange)="settingChanged()"
|
||||
></ion-toggle>
|
||||
<!-- else show select input -->
|
||||
<ion-select *ngIf="typeOf(setting.defaultValue) !== 'boolean'" interface="popover" [(ngModel)]="setting.value" (ionChange)="settingChanged()">
|
||||
<ion-select-option *ngFor="let val of setting.values, index as i" [value]="val">
|
||||
<div *ngIf="typeOf(val) !== 'number'">{{ ('values' | thingTranslate: setting)[i] | titlecase }}</div>
|
||||
<ion-select
|
||||
*ngIf="typeOf(setting.defaultValue) !== 'boolean'"
|
||||
interface="popover"
|
||||
[(ngModel)]="setting.value"
|
||||
(ionChange)="settingChanged()"
|
||||
>
|
||||
<ion-select-option
|
||||
*ngFor="let val of setting.values; index as i"
|
||||
[value]="val"
|
||||
>
|
||||
<div *ngIf="typeOf(val) !== 'number'">
|
||||
{{ ('values' | thingTranslate: setting)[i] | titlecase }}
|
||||
</div>
|
||||
<div *ngIf="typeOf(val) === 'number'">{{ val }}</div>
|
||||
</ion-select-option>
|
||||
</ion-select>
|
||||
@@ -39,9 +82,18 @@
|
||||
|
||||
<ion-item *ngSwitchCase="'multiple choice'">
|
||||
<ion-label></ion-label>
|
||||
<ion-select [(ngModel)]="setting.value" multiple="true" (ionChange)="settingChanged()">
|
||||
<ion-select-option *ngFor="let val of setting.values, index as i" [value]="val">
|
||||
<div *ngIf="typeOf(val) !== 'number'">{{ ('values' | thingTranslate: setting)[i] | titlecase }}</div>
|
||||
<ion-select
|
||||
[(ngModel)]="setting.value"
|
||||
multiple="true"
|
||||
(ionChange)="settingChanged()"
|
||||
>
|
||||
<ion-select-option
|
||||
*ngFor="let val of setting.values; index as i"
|
||||
[value]="val"
|
||||
>
|
||||
<div *ngIf="typeOf(val) !== 'number'">
|
||||
{{ ('values' | thingTranslate: setting)[i] | titlecase }}
|
||||
</div>
|
||||
<div *ngIf="typeOf(val) === 'number'">{{ val }}</div>
|
||||
</ion-select-option>
|
||||
</ion-select>
|
||||
|
||||
@@ -12,31 +12,35 @@
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {ChangeDetectorRef, Component} from '@angular/core';
|
||||
import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
|
||||
import {AlertController, ToastController} from '@ionic/angular';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {SCSettingMeta} from '@openstapps/core';
|
||||
import {SettingsCache, SettingsProvider} from '../settings.provider';
|
||||
/**
|
||||
* Settings page component
|
||||
*/
|
||||
|
||||
/**
|
||||
* Settings page component
|
||||
*/
|
||||
@Component({
|
||||
selector: 'stapps-settings-page',
|
||||
templateUrl: 'settings-page.html',
|
||||
})
|
||||
export class SettingsPageComponent {
|
||||
export class SettingsPageComponent implements OnInit {
|
||||
/**
|
||||
* Order of the categories
|
||||
*/
|
||||
categoriesOrder: string[];
|
||||
|
||||
/**
|
||||
* Meta information about settings
|
||||
*/
|
||||
meta = SCSettingMeta;
|
||||
|
||||
/**
|
||||
* Mapping of Object.keys for Html usage
|
||||
*/
|
||||
objectKeys = Object.keys;
|
||||
|
||||
/**
|
||||
* Container to cache settings from provider
|
||||
*/
|
||||
@@ -50,11 +54,13 @@ export class SettingsPageComponent {
|
||||
* @param translateService TranslateService
|
||||
* @param changeDetectorRef ChangeDetectorRef
|
||||
*/
|
||||
constructor(private readonly alertController: AlertController,
|
||||
private readonly settingsProvider: SettingsProvider,
|
||||
private readonly toastController: ToastController,
|
||||
private readonly translateService: TranslateService,
|
||||
private readonly changeDetectorRef: ChangeDetectorRef) {
|
||||
constructor(
|
||||
private readonly alertController: AlertController,
|
||||
private readonly settingsProvider: SettingsProvider,
|
||||
private readonly toastController: ToastController,
|
||||
private readonly translateService: TranslateService,
|
||||
private readonly changeDetectorRef: ChangeDetectorRef,
|
||||
) {
|
||||
this.settingsCache = {};
|
||||
}
|
||||
|
||||
@@ -92,13 +98,17 @@ export class SettingsPageComponent {
|
||||
* Presents an alert to the user to reset settings to default values
|
||||
*/
|
||||
async presentResetAlert() {
|
||||
const cancelText = await this.translateService.get('settings.resetAlert.buttonCancel')
|
||||
const cancelText = await this.translateService
|
||||
.get('settings.resetAlert.buttonCancel')
|
||||
.toPromise();
|
||||
const yesText = await this.translateService.get('settings.resetAlert.buttonYes')
|
||||
const yesText = await this.translateService
|
||||
.get('settings.resetAlert.buttonYes')
|
||||
.toPromise();
|
||||
const title = await this.translateService.get('settings.resetAlert.title')
|
||||
const title = await this.translateService
|
||||
.get('settings.resetAlert.title')
|
||||
.toPromise();
|
||||
const message = await this.translateService.get('settings.resetAlert.message')
|
||||
const message = await this.translateService
|
||||
.get('settings.resetAlert.message')
|
||||
.toPromise();
|
||||
|
||||
const alert = await this.alertController.create({
|
||||
@@ -117,7 +127,7 @@ export class SettingsPageComponent {
|
||||
header: title,
|
||||
message: message,
|
||||
});
|
||||
alert.present();
|
||||
await alert.present();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,15 +139,17 @@ export class SettingsPageComponent {
|
||||
await this.presentSettingsResetToast();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows alert to reset settings
|
||||
*/
|
||||
/**
|
||||
* Shows alert to reset settings
|
||||
*/
|
||||
async showResetAlert() {
|
||||
const alert = await this.alertController.create({
|
||||
buttons: [
|
||||
{
|
||||
role: 'cancel',
|
||||
text: this.translateService.instant('settings.resetAlert.buttonCancel'),
|
||||
text: this.translateService.instant(
|
||||
'settings.resetAlert.buttonCancel',
|
||||
),
|
||||
},
|
||||
{
|
||||
handler: async () => {
|
||||
@@ -150,6 +162,6 @@ export class SettingsPageComponent {
|
||||
message: this.translateService.instant('settings.resetAlert.message'),
|
||||
});
|
||||
|
||||
alert.present();
|
||||
await alert.present();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,21 +4,40 @@
|
||||
<ion-back-button></ion-back-button>
|
||||
<ion-menu-button></ion-menu-button>
|
||||
</ion-buttons>
|
||||
<ion-title>{{'settings.title' | translate | titlecase}}</ion-title>
|
||||
<ion-title>{{ 'settings.title' | translate | titlecase }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-list *ngFor="let categoryKey of categoriesOrder ">
|
||||
<ion-list *ngFor="let categoryKey of categoriesOrder">
|
||||
<div *ngIf="objectKeys(settingsCache).includes(categoryKey)">
|
||||
<ion-item-divider>
|
||||
<h5>{{ 'categories[0]' | thingTranslate: settingsCache[categoryKey]?.settings[objectKeys(settingsCache[categoryKey]?.settings)[0]] | titlecase }} </h5>
|
||||
<h5>
|
||||
{{
|
||||
'categories[0]'
|
||||
| thingTranslate
|
||||
: settingsCache[categoryKey]?.settings[
|
||||
objectKeys(settingsCache[categoryKey]?.settings)[0]
|
||||
]
|
||||
| titlecase
|
||||
}}
|
||||
</h5>
|
||||
</ion-item-divider>
|
||||
<stapps-settings-item *ngFor="let settingKeys of objectKeys(settingsCache[categoryKey].settings)" [setting]="settingsCache[categoryKey].settings[settingKeys]"></stapps-settings-item>
|
||||
<stapps-settings-item
|
||||
*ngFor="
|
||||
let settingKeys of objectKeys(settingsCache[categoryKey].settings)
|
||||
"
|
||||
[setting]="settingsCache[categoryKey].settings[settingKeys]"
|
||||
></stapps-settings-item>
|
||||
</div>
|
||||
</ion-list>
|
||||
<ion-button color="medium" expand="block" fill="outline" (click)="presentResetAlert()">
|
||||
{{'settings.resetSettings' | translate}}
|
||||
<ion-button
|
||||
color="medium"
|
||||
expand="block"
|
||||
fill="outline"
|
||||
(click)="presentResetAlert()"
|
||||
>
|
||||
{{ 'settings.resetSettings' | translate }}
|
||||
<ion-icon slot="start" name="undo"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-content>
|
||||
|
||||
@@ -33,24 +33,16 @@ const settingsRoutes: Routes = [
|
||||
* Settings Module
|
||||
*/
|
||||
@NgModule({
|
||||
declarations: [
|
||||
SettingsPageComponent,
|
||||
SettingsItemComponent,
|
||||
],
|
||||
exports: [
|
||||
SettingsItemComponent,
|
||||
],
|
||||
declarations: [SettingsPageComponent, SettingsItemComponent],
|
||||
exports: [SettingsItemComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
IonicModule.forRoot(),
|
||||
TranslateModule.forChild(),
|
||||
ThingTranslateModule.forChild(),
|
||||
RouterModule.forChild(settingsRoutes),
|
||||
ThingTranslateModule.forChild(),
|
||||
TranslateModule.forChild(),
|
||||
],
|
||||
providers: [
|
||||
ConfigProvider,
|
||||
SettingsProvider,
|
||||
],
|
||||
providers: [ConfigProvider, SettingsProvider],
|
||||
})
|
||||
export class SettingsModule {}
|
||||
|
||||
@@ -13,10 +13,19 @@
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {SCSetting, SCThingOriginType, SCThingType, SCSettingInputType} from '@openstapps/core';
|
||||
import {
|
||||
SCSetting,
|
||||
SCThingOriginType,
|
||||
SCThingType,
|
||||
SCSettingInputType,
|
||||
} from '@openstapps/core';
|
||||
import {ConfigProvider} from '../config/config.provider';
|
||||
import {StorageProvider} from '../storage/storage.provider';
|
||||
import {SettingsProvider, SettingValuesContainer, STORAGE_KEY_SETTING_VALUES} from './settings.provider';
|
||||
import {
|
||||
SettingsProvider,
|
||||
SettingValuesContainer,
|
||||
STORAGE_KEY_SETTING_VALUES,
|
||||
} from './settings.provider';
|
||||
|
||||
describe('SettingsProvider', () => {
|
||||
let configProviderSpy: jasmine.SpyObj<ConfigProvider>;
|
||||
@@ -24,50 +33,73 @@ describe('SettingsProvider', () => {
|
||||
let storageProviderSpy: jasmine.SpyObj<StorageProvider>;
|
||||
|
||||
beforeEach(async () => {
|
||||
const storageProviderMethodSpy = jasmine.createSpyObj('StorageProvider', ['init', 'get', 'has', 'put']);
|
||||
const configProviderMethodSpy = jasmine.createSpyObj('ConfigProvider', ['getValue']);
|
||||
const storageProviderMethodSpy = jasmine.createSpyObj('StorageProvider', [
|
||||
'init',
|
||||
'get',
|
||||
'has',
|
||||
'put',
|
||||
]);
|
||||
const configProviderMethodSpy = jasmine.createSpyObj('ConfigProvider', [
|
||||
'getValue',
|
||||
]);
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [],
|
||||
providers: [
|
||||
SettingsProvider,
|
||||
{
|
||||
provide: StorageProvider, useValue: storageProviderMethodSpy,
|
||||
provide: StorageProvider,
|
||||
useValue: storageProviderMethodSpy,
|
||||
},
|
||||
{
|
||||
provide: ConfigProvider, useValue: configProviderMethodSpy,
|
||||
provide: ConfigProvider,
|
||||
useValue: configProviderMethodSpy,
|
||||
},
|
||||
],
|
||||
});
|
||||
configProviderSpy = TestBed.get(ConfigProvider);
|
||||
// set settings returned from config
|
||||
configProviderSpy.getValue.and.returnValue(Promise.resolve(CONFIG_SETTINGS_MOCK));
|
||||
configProviderSpy.getValue.and.returnValue(
|
||||
Promise.resolve(CONFIG_SETTINGS_MOCK),
|
||||
);
|
||||
settingsProvider = TestBed.get(SettingsProvider);
|
||||
storageProviderSpy = TestBed.get(StorageProvider);
|
||||
storageProviderMethodSpy.has.and.returnValue(false);
|
||||
});
|
||||
|
||||
it('should provide and get setting', async () => {
|
||||
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])));
|
||||
const setting: SCSetting = await settingsProvider
|
||||
.getSetting(CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name);
|
||||
await settingsProvider.provideSetting(
|
||||
JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])),
|
||||
);
|
||||
const setting: SCSetting = await settingsProvider.getSetting(
|
||||
CONFIG_SETTINGS_MOCK[0].categories[0],
|
||||
CONFIG_SETTINGS_MOCK[0].name,
|
||||
);
|
||||
await expect(setting.value).toBeDefined();
|
||||
});
|
||||
|
||||
it('should provide and get settings value', async () => {
|
||||
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])));
|
||||
const value = await settingsProvider
|
||||
.getValue(CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name);
|
||||
await settingsProvider.provideSetting(
|
||||
JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])),
|
||||
);
|
||||
const value = await settingsProvider.getValue(
|
||||
CONFIG_SETTINGS_MOCK[0].categories[0],
|
||||
CONFIG_SETTINGS_MOCK[0].name,
|
||||
);
|
||||
await expect(value).toEqual(CONFIG_SETTINGS_MOCK[0].defaultValue);
|
||||
});
|
||||
|
||||
it('should get persisted setting value', async () => {
|
||||
// set return values of storage
|
||||
storageProviderSpy.has.and.returnValue(Promise.resolve(true));
|
||||
storageProviderSpy.get.and.returnValue(Promise.resolve(SETTING_VALUES_MOCK));
|
||||
storageProviderSpy.get.and.returnValue(
|
||||
Promise.resolve(SETTING_VALUES_MOCK),
|
||||
);
|
||||
|
||||
const value = await settingsProvider
|
||||
.getValue(CONFIG_SETTINGS_MOCK[3].categories[0], CONFIG_SETTINGS_MOCK[3].name);
|
||||
const value = await settingsProvider.getValue(
|
||||
CONFIG_SETTINGS_MOCK[3].categories[0],
|
||||
CONFIG_SETTINGS_MOCK[3].name,
|
||||
);
|
||||
await expect(value).toEqual(SETTING_VALUES_MOCK.profile.group);
|
||||
});
|
||||
|
||||
@@ -75,74 +107,100 @@ describe('SettingsProvider', () => {
|
||||
// set return values of spy objects
|
||||
storageProviderSpy.has.and.returnValue(Promise.resolve(true));
|
||||
storageProviderSpy.get.and.returnValue(Promise.resolve([]));
|
||||
const value = await settingsProvider
|
||||
.getValue(CONFIG_SETTINGS_MOCK[3].categories[0], CONFIG_SETTINGS_MOCK[3].name);
|
||||
const value = await settingsProvider.getValue(
|
||||
CONFIG_SETTINGS_MOCK[3].categories[0],
|
||||
CONFIG_SETTINGS_MOCK[3].name,
|
||||
);
|
||||
await expect(value).toEqual(CONFIG_SETTINGS_MOCK[3].defaultValue);
|
||||
});
|
||||
|
||||
it('should keep persisted setting values from settings that are not contained in loaded config', async () => {
|
||||
const settings = [
|
||||
CONFIG_SETTINGS_MOCK[4],
|
||||
CONFIG_SETTINGS_MOCK[5],
|
||||
];
|
||||
const settings = [CONFIG_SETTINGS_MOCK[4], CONFIG_SETTINGS_MOCK[5]];
|
||||
configProviderSpy.getValue.and.returnValue(Promise.resolve(settings));
|
||||
storageProviderSpy.has.and.returnValue(Promise.resolve(true));
|
||||
storageProviderSpy.get.and.returnValue(Promise.resolve(SETTING_VALUES_MOCK));
|
||||
storageProviderSpy.get.and.returnValue(
|
||||
Promise.resolve(SETTING_VALUES_MOCK),
|
||||
);
|
||||
await settingsProvider.init();
|
||||
await expect(storageProviderSpy.put).toHaveBeenCalledWith(STORAGE_KEY_SETTING_VALUES, SETTING_VALUES_MOCK);
|
||||
await expect(storageProviderSpy.put).toHaveBeenCalledWith(
|
||||
STORAGE_KEY_SETTING_VALUES,
|
||||
SETTING_VALUES_MOCK,
|
||||
);
|
||||
});
|
||||
|
||||
it('should set value of a provided setting', async () => {
|
||||
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[1])));
|
||||
await settingsProvider
|
||||
.setSettingValue(CONFIG_SETTINGS_MOCK[1].categories[0], CONFIG_SETTINGS_MOCK[1].name, 'updated');
|
||||
const value = await settingsProvider
|
||||
.getValue(CONFIG_SETTINGS_MOCK[1].categories[0], CONFIG_SETTINGS_MOCK[1].name);
|
||||
await settingsProvider.provideSetting(
|
||||
JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[1])),
|
||||
);
|
||||
await settingsProvider.setSettingValue(
|
||||
CONFIG_SETTINGS_MOCK[1].categories[0],
|
||||
CONFIG_SETTINGS_MOCK[1].name,
|
||||
'updated',
|
||||
);
|
||||
const value = await settingsProvider.getValue(
|
||||
CONFIG_SETTINGS_MOCK[1].categories[0],
|
||||
CONFIG_SETTINGS_MOCK[1].name,
|
||||
);
|
||||
await expect(value).toEqual('updated');
|
||||
});
|
||||
|
||||
it('should return copy of settingsCache', async () => {
|
||||
const category = CONFIG_SETTINGS_MOCK[0].categories[0];
|
||||
const name = CONFIG_SETTINGS_MOCK[0].name;
|
||||
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])));
|
||||
await settingsProvider.provideSetting(
|
||||
JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])),
|
||||
);
|
||||
const settings = await settingsProvider.getCache();
|
||||
settings[category].settings[name].value = 'testValue';
|
||||
// cached setting value should still be defaultValue
|
||||
await expect((await settingsProvider.getValue(category, name)))
|
||||
.toEqual(CONFIG_SETTINGS_MOCK[0].defaultValue);
|
||||
await expect(await settingsProvider.getValue(category, name)).toEqual(
|
||||
CONFIG_SETTINGS_MOCK[0].defaultValue,
|
||||
);
|
||||
});
|
||||
|
||||
it('should call storage put on setSettingValue', async () => {
|
||||
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])));
|
||||
await settingsProvider
|
||||
.setSettingValue(CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name, '');
|
||||
await settingsProvider.provideSetting(
|
||||
JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])),
|
||||
);
|
||||
await settingsProvider.setSettingValue(
|
||||
CONFIG_SETTINGS_MOCK[0].categories[0],
|
||||
CONFIG_SETTINGS_MOCK[0].name,
|
||||
'',
|
||||
);
|
||||
await expect(storageProviderSpy.put).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should clear settings', async () => {
|
||||
await settingsProvider.reset();
|
||||
await expect(storageProviderSpy.put).toHaveBeenCalledWith(STORAGE_KEY_SETTING_VALUES, {});
|
||||
await expect(storageProviderSpy.put).toHaveBeenCalledWith(
|
||||
STORAGE_KEY_SETTING_VALUES,
|
||||
{},
|
||||
);
|
||||
});
|
||||
|
||||
it('should reset settings', async () => {
|
||||
const category = CONFIG_SETTINGS_MOCK[0].categories[0];
|
||||
const name = CONFIG_SETTINGS_MOCK[0].name;
|
||||
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])));
|
||||
await settingsProvider.provideSetting(
|
||||
JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])),
|
||||
);
|
||||
await settingsProvider.setSettingValue(category, name, 'guest');
|
||||
await settingsProvider.resetDefault();
|
||||
const value = await settingsProvider
|
||||
.getValue(CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name);
|
||||
const value = await settingsProvider.getValue(
|
||||
CONFIG_SETTINGS_MOCK[0].categories[0],
|
||||
CONFIG_SETTINGS_MOCK[0].name,
|
||||
);
|
||||
await expect(value).toEqual(CONFIG_SETTINGS_MOCK[0].defaultValue);
|
||||
});
|
||||
|
||||
it('should validate wrong values for inputType text', async () => {
|
||||
await testValue(CONFIG_SETTINGS_MOCK[0], 123456789);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[0], 123_456_789);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[0], false);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[0], []);
|
||||
});
|
||||
|
||||
it('should validate wrong values for inputType password', async () => {
|
||||
await testValue(CONFIG_SETTINGS_MOCK[0], 123456789);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[0], 123_456_789);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[0], false);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[0], []);
|
||||
});
|
||||
@@ -155,34 +213,43 @@ describe('SettingsProvider', () => {
|
||||
|
||||
it('should validate wrong values for inputType singleChoice text', async () => {
|
||||
await testValue(CONFIG_SETTINGS_MOCK[3], '');
|
||||
await testValue(CONFIG_SETTINGS_MOCK[3], 123456);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[3], 123_456);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[3], false);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[3], []);
|
||||
});
|
||||
|
||||
it('should validate wrong values for inputType singleChoice boolean', async () => {
|
||||
await testValue(CONFIG_SETTINGS_MOCK[5], '');
|
||||
await testValue(CONFIG_SETTINGS_MOCK[5], 123456);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[5], 123_456);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[5], []);
|
||||
});
|
||||
|
||||
it('should validate wrong values for inputType multipleChoice', async () => {
|
||||
await testValue(CONFIG_SETTINGS_MOCK[6], '');
|
||||
await testValue(CONFIG_SETTINGS_MOCK[6], 123456);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[6], 123_456);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[6], false);
|
||||
await testValue(CONFIG_SETTINGS_MOCK[6], [1, 9]);
|
||||
});
|
||||
|
||||
async function testValue(setting: SCSetting, value: any) {
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
async function testValue(setting: SCSetting, value: unknown) {
|
||||
let error: Error;
|
||||
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(setting)));
|
||||
try {
|
||||
await settingsProvider.setSettingValue(setting.categories[0], setting.name, value);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
await settingsProvider.setSettingValue(
|
||||
setting.categories[0],
|
||||
setting.name,
|
||||
value as never,
|
||||
);
|
||||
} catch (error_) {
|
||||
error = error_;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
await expect(error).toBeDefined();
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
await expect(error.message).toMatch(/is not valid/);
|
||||
}
|
||||
@@ -270,13 +337,15 @@ describe('SettingsProvider', () => {
|
||||
},
|
||||
translations: {
|
||||
de: {
|
||||
description: 'Mit welcher Benutzergruppe soll die App verwendet werden?'
|
||||
+ ' Die Einstellung wird beispielsweise für die Vorauswahl der Preiskategorie der Mensa verwendet.',
|
||||
description:
|
||||
'Mit welcher Benutzergruppe soll die App verwendet werden?' +
|
||||
' Die Einstellung wird beispielsweise für die Vorauswahl der Preiskategorie der Mensa verwendet.',
|
||||
name: 'Gruppe',
|
||||
},
|
||||
en: {
|
||||
description: 'The user group the app is going to be used.'
|
||||
+ 'This settings for example is getting used for the predefined price category of mensa meals.',
|
||||
description:
|
||||
'The user group the app is going to be used.' +
|
||||
'This settings for example is getting used for the predefined price category of mensa meals.',
|
||||
name: 'Group',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -13,11 +13,7 @@
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {Injectable} from '@angular/core';
|
||||
import {
|
||||
SCSetting,
|
||||
SCSettingValue,
|
||||
SCSettingValues,
|
||||
} from '@openstapps/core';
|
||||
import {SCSetting, SCSettingValue, SCSettingValues} from '@openstapps/core';
|
||||
import deepMerge from 'deepmerge';
|
||||
import {Subject} from 'rxjs';
|
||||
import {ConfigProvider} from '../config/config.provider';
|
||||
@@ -38,7 +34,7 @@ export interface CategoryWithSettings {
|
||||
/**
|
||||
* Settings that belong in this category
|
||||
*/
|
||||
settings: { [key: string]: SCSetting; };
|
||||
settings: {[key: string]: SCSetting};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,14 +95,17 @@ export class SettingsProvider {
|
||||
* Source of settings actions
|
||||
*/
|
||||
private settingsActionSource = new Subject<SettingsAction>();
|
||||
|
||||
/**
|
||||
* Order of the setting categories
|
||||
*/
|
||||
categoriesOrder: string[];
|
||||
|
||||
/**
|
||||
* Settings actions observable
|
||||
*/
|
||||
settingsActionChanged$ = this.settingsActionSource.asObservable();
|
||||
|
||||
/**
|
||||
* Cache for the imported settings
|
||||
*/
|
||||
@@ -114,6 +113,7 @@ export class SettingsProvider {
|
||||
|
||||
/**
|
||||
* Return true if all given values are valid to possible values in given settingInput
|
||||
*
|
||||
* @param possibleValues Possible values
|
||||
* @param enteredValues Entered value
|
||||
*/
|
||||
@@ -121,7 +121,7 @@ export class SettingsProvider {
|
||||
possibleValues: SCSettingValues | undefined,
|
||||
enteredValues: SCSettingValues,
|
||||
): boolean {
|
||||
if ( typeof possibleValues === 'undefined' ) {
|
||||
if (typeof possibleValues === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -136,6 +136,7 @@ export class SettingsProvider {
|
||||
|
||||
/**
|
||||
* Returns true if given value is valid to possible values in given settingInput
|
||||
*
|
||||
* @param possibleValues Possible values
|
||||
* @param enteredValue Entered value
|
||||
*/
|
||||
@@ -143,21 +144,27 @@ export class SettingsProvider {
|
||||
possibleValues: SCSettingValues | undefined,
|
||||
enteredValue: SCSettingValue,
|
||||
): boolean {
|
||||
if ( typeof possibleValues === 'undefined' ) {
|
||||
if (typeof possibleValues === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return possibleValues !== undefined
|
||||
&& (Array.isArray(possibleValues)
|
||||
&& possibleValues.includes(enteredValue));
|
||||
return (
|
||||
possibleValues !== undefined &&
|
||||
Array.isArray(possibleValues) &&
|
||||
possibleValues.includes(enteredValue)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates value for given settings inputType. Returns true if value is valid.
|
||||
*
|
||||
* @param setting setting to check value against
|
||||
* @param value value to validate
|
||||
*/
|
||||
public static validateValue(setting: SCSetting, value: SCSettingValue | SCSettingValues): boolean {
|
||||
public static validateValue(
|
||||
setting: SCSetting,
|
||||
value: SCSettingValue | SCSettingValues,
|
||||
): boolean {
|
||||
let isValueValid = false;
|
||||
switch (setting.inputType) {
|
||||
case 'number':
|
||||
@@ -166,11 +173,9 @@ export class SettingsProvider {
|
||||
}
|
||||
break;
|
||||
case 'multiple choice':
|
||||
if (!Array.isArray(value)) {
|
||||
isValueValid = false;
|
||||
} else {
|
||||
isValueValid = SettingsProvider.checkMultipleChoiceValue(setting.values, value);
|
||||
}
|
||||
isValueValid = !Array.isArray(value)
|
||||
? false
|
||||
: SettingsProvider.checkMultipleChoiceValue(setting.values, value);
|
||||
break;
|
||||
case 'password':
|
||||
case 'text':
|
||||
@@ -179,11 +184,9 @@ export class SettingsProvider {
|
||||
}
|
||||
break;
|
||||
case 'single choice':
|
||||
if (Array.isArray(value)) {
|
||||
isValueValid = false;
|
||||
} else {
|
||||
isValueValid = SettingsProvider.checkSingleChoiceValue(setting.values, value);
|
||||
}
|
||||
isValueValid = Array.isArray(value)
|
||||
? false
|
||||
: SettingsProvider.checkSingleChoiceValue(setting.values, value);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
@@ -196,14 +199,17 @@ export class SettingsProvider {
|
||||
* @param storage TODO
|
||||
* @param configProvider TODO
|
||||
*/
|
||||
constructor(private readonly storage: StorageProvider,
|
||||
private readonly configProvider: ConfigProvider) {
|
||||
constructor(
|
||||
private readonly storage: StorageProvider,
|
||||
private readonly configProvider: ConfigProvider,
|
||||
) {
|
||||
this.categoriesOrder = [];
|
||||
this.settingsCache = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an Setting to the Cache if not exist and set undefined value to defaultValue
|
||||
*
|
||||
* @param setting Setting with categories, defaultValue, name, input type and valid values
|
||||
*/
|
||||
private addSetting(setting: SCSetting): void {
|
||||
@@ -214,7 +220,8 @@ export class SettingsProvider {
|
||||
if (setting.value === undefined) {
|
||||
setting.value = setting.defaultValue;
|
||||
}
|
||||
this.settingsCache[setting.categories[0]].settings[setting.name] = setting;
|
||||
this.settingsCache[setting.categories[0]].settings[setting.name] =
|
||||
setting;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +233,9 @@ export class SettingsProvider {
|
||||
// iterate through keys of categories
|
||||
for (const categoryKey of Object.keys(this.settingsCache)) {
|
||||
// iterate through keys of settingValueContainer
|
||||
for (const settingKey of Object.keys(this.settingsCache[categoryKey].settings)) {
|
||||
for (const settingKey of Object.keys(
|
||||
this.settingsCache[categoryKey].settings,
|
||||
)) {
|
||||
if (typeof settingValuesContainer[categoryKey] === 'undefined') {
|
||||
settingValuesContainer[categoryKey] = {};
|
||||
}
|
||||
@@ -240,6 +249,7 @@ export class SettingsProvider {
|
||||
|
||||
/**
|
||||
* Add category if not exists
|
||||
*
|
||||
* @param category the category to provide
|
||||
*/
|
||||
private provideCategory(category: string): void {
|
||||
@@ -256,6 +266,7 @@ export class SettingsProvider {
|
||||
|
||||
/**
|
||||
* Returns true if category exists
|
||||
*
|
||||
* @param category Category key name
|
||||
*/
|
||||
public categoryExists(category: string): boolean {
|
||||
@@ -280,32 +291,39 @@ export class SettingsProvider {
|
||||
|
||||
/**
|
||||
* Returns copy of a setting if exist
|
||||
*
|
||||
* @param category the category of requested setting
|
||||
* @param name the name of requested setting
|
||||
*
|
||||
* @throws Exception if setting is not provided
|
||||
*/
|
||||
public async getSetting(category: string, name: string): Promise<SCSetting> {
|
||||
await this.init();
|
||||
if (this.settingExists(category, name)) {
|
||||
// return a copy of the settings
|
||||
return JSON.parse(JSON.stringify(this.settingsCache[category].settings[name]));
|
||||
return JSON.parse(
|
||||
JSON.stringify(this.settingsCache[category].settings[name]),
|
||||
);
|
||||
}
|
||||
throw new Error(`Setting "${name}" not provided`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns copy of a settings value if exist
|
||||
*
|
||||
* @param category the category of requested setting
|
||||
* @param name the name of requested setting
|
||||
*
|
||||
* @throws Exception if setting is not provided
|
||||
*/
|
||||
public async getValue(category: string, name: string): Promise<SCSettingValue | SCSettingValues> {
|
||||
public async getValue(
|
||||
category: string,
|
||||
name: string,
|
||||
): Promise<SCSettingValue | SCSettingValues> {
|
||||
await this.init();
|
||||
if (this.settingExists(category, name)) {
|
||||
// return a copy of the settings value
|
||||
return JSON.parse(JSON.stringify(this.settingsCache[category].settings[name].value));
|
||||
return JSON.parse(
|
||||
JSON.stringify(this.settingsCache[category].settings[name].value),
|
||||
);
|
||||
}
|
||||
throw new Error(`Setting "${name}" not provided`);
|
||||
}
|
||||
@@ -313,31 +331,39 @@ export class SettingsProvider {
|
||||
/**
|
||||
* Initializes settings from config and stored values if exist
|
||||
*/
|
||||
public async init(): Promise<void> {
|
||||
public async init(): Promise<void> {
|
||||
try {
|
||||
const settings: SCSetting[] = (await this.configProvider.getValue('settings')) as SCSetting[];
|
||||
settings.forEach((setting) => this.addSetting(setting));
|
||||
const settings: SCSetting[] = (await this.configProvider.getValue(
|
||||
'settings',
|
||||
)) as SCSetting[];
|
||||
for (const setting of settings) this.addSetting(setting);
|
||||
|
||||
for (const category of Object.keys(this.settingsCache)) {
|
||||
if (!this.categoriesOrder.includes(category)) {
|
||||
this.categoriesOrder.push(category);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
this.settingsCache = {};
|
||||
}
|
||||
|
||||
if (await this.storage.has(STORAGE_KEY_SETTING_VALUES)) {
|
||||
// get setting values from StorageProvider into settingsCache
|
||||
const valuesContainer: SettingValuesContainer =
|
||||
await this.storage.get<SettingValuesContainer>(STORAGE_KEY_SETTING_VALUES);
|
||||
await this.storage.get<SettingValuesContainer>(
|
||||
STORAGE_KEY_SETTING_VALUES,
|
||||
);
|
||||
// iterate through keys of categories
|
||||
for (const categoryKey of Object.keys(this.settingsCache)) {
|
||||
// iterate through setting keys of category
|
||||
for (const settingKey of Object.keys(this.settingsCache[categoryKey].settings)) {
|
||||
for (const settingKey of Object.keys(
|
||||
this.settingsCache[categoryKey].settings,
|
||||
)) {
|
||||
// if saved setting value exists set it, otherwise set to default value
|
||||
if (typeof valuesContainer[categoryKey] !== 'undefined'
|
||||
&& typeof valuesContainer[categoryKey][settingKey] !== 'undefined') {
|
||||
if (
|
||||
typeof valuesContainer[categoryKey] !== 'undefined' &&
|
||||
typeof valuesContainer[categoryKey][settingKey] !== 'undefined'
|
||||
) {
|
||||
this.settingsCache[categoryKey].settings[settingKey].value =
|
||||
valuesContainer[categoryKey][settingKey];
|
||||
} else {
|
||||
@@ -352,6 +378,7 @@ export class SettingsProvider {
|
||||
|
||||
/**
|
||||
* Adds given setting and its category if not exist
|
||||
*
|
||||
* @param setting the setting to add
|
||||
*/
|
||||
public provideSetting(setting: SCSetting): void {
|
||||
@@ -371,7 +398,9 @@ export class SettingsProvider {
|
||||
*/
|
||||
async resetDefault(): Promise<void> {
|
||||
for (const catKey of Object.keys(this.settingsCache)) {
|
||||
for (const settingKey of Object.keys(this.settingsCache[catKey].settings)) {
|
||||
for (const settingKey of Object.keys(
|
||||
this.settingsCache[catKey].settings,
|
||||
)) {
|
||||
const settingInput = this.settingsCache[catKey].settings[settingKey];
|
||||
settingInput.value = settingInput.defaultValue;
|
||||
}
|
||||
@@ -385,18 +414,29 @@ export class SettingsProvider {
|
||||
public async saveSettingValues(): Promise<void> {
|
||||
if (await this.storage.has(STORAGE_KEY_SETTING_VALUES)) {
|
||||
const savedSettingsValues: SettingValuesContainer =
|
||||
await this.storage.get<SettingValuesContainer>(STORAGE_KEY_SETTING_VALUES);
|
||||
await this.storage.get<SettingValuesContainer>(
|
||||
STORAGE_KEY_SETTING_VALUES,
|
||||
);
|
||||
const cacheSettingsValues = this.getSettingValuesFromCache();
|
||||
const mergedSettingValues = deepMerge(savedSettingsValues, cacheSettingsValues);
|
||||
await this.storage
|
||||
.put<SettingValuesContainer>(STORAGE_KEY_SETTING_VALUES, mergedSettingValues);
|
||||
const mergedSettingValues = deepMerge(
|
||||
savedSettingsValues,
|
||||
cacheSettingsValues,
|
||||
);
|
||||
await this.storage.put<SettingValuesContainer>(
|
||||
STORAGE_KEY_SETTING_VALUES,
|
||||
mergedSettingValues,
|
||||
);
|
||||
} else {
|
||||
await this.storage.put<SettingValuesContainer>(STORAGE_KEY_SETTING_VALUES, this.getSettingValuesFromCache());
|
||||
await this.storage.put<SettingValuesContainer>(
|
||||
STORAGE_KEY_SETTING_VALUES,
|
||||
this.getSettingValuesFromCache(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the order the given categories show up in the settings page
|
||||
*
|
||||
* @param categoryNames the order of the categories
|
||||
*/
|
||||
public setCategoriesOrder(categoryNames: string[]) {
|
||||
@@ -409,11 +449,13 @@ export class SettingsProvider {
|
||||
* @param category Category key name
|
||||
* @param name Setting key name
|
||||
* @param value Value to be set
|
||||
*
|
||||
* @throws Exception if setting is not provided or value not valid to the settings inputType
|
||||
*/
|
||||
public async setSettingValue(category: string, name: string,
|
||||
value: SCSettingValue | SCSettingValues): Promise<void> {
|
||||
public async setSettingValue(
|
||||
category: string,
|
||||
name: string,
|
||||
value: SCSettingValue | SCSettingValues,
|
||||
): Promise<void> {
|
||||
await this.init();
|
||||
if (this.settingExists(category, name)) {
|
||||
const setting: SCSetting = this.settingsCache[category].settings[name];
|
||||
@@ -423,7 +465,10 @@ export class SettingsProvider {
|
||||
this.settingsCache[category].settings[name].value = value;
|
||||
await this.saveSettingValues();
|
||||
// publish setting changes
|
||||
this.settingsActionSource.next({type: 'stapps.settings.changed', payload: {category, name, value}});
|
||||
this.settingsActionSource.next({
|
||||
type: 'stapps.settings.changed',
|
||||
payload: {category, name, value},
|
||||
});
|
||||
} else {
|
||||
throw new Error(`Value "${value}" of type
|
||||
${typeof value} is not valid for ${setting.inputType}`);
|
||||
@@ -435,10 +480,14 @@ export class SettingsProvider {
|
||||
|
||||
/**
|
||||
* Returns true if setting in category exists
|
||||
*
|
||||
* @param category Category key name
|
||||
* @param setting Setting key name
|
||||
*/
|
||||
public settingExists(category: string, setting: string): boolean {
|
||||
return this.categoryExists(category) && this.settingsCache[category].settings[setting] !== undefined;
|
||||
return (
|
||||
this.categoryExists(category) &&
|
||||
this.settingsCache[category].settings[setting] !== undefined
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user