mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-23 01:27:14 +02:00
Implementing template config savings #569
This commit is contained in:
parent
9c4178e508
commit
9ac67ead63
@ -1,13 +1,14 @@
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { ErrorCodes, ErrorDTO } from '../../common/entities/Error';
|
||||
import { Message } from '../../common/entities/Message';
|
||||
import { Config, PrivateConfigClass } from '../../common/config/private/Config';
|
||||
import { UserDTO, UserRoles } from '../../common/entities/UserDTO';
|
||||
import { NotificationManager } from '../model/NotifocationManager';
|
||||
import { Logger } from '../Logger';
|
||||
import { SharingDTO } from '../../common/entities/SharingDTO';
|
||||
import { Utils } from '../../common/Utils';
|
||||
import { LoggerRouter } from '../routes/LoggerRouter';
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||
import {Message} from '../../common/entities/Message';
|
||||
import {Config, PrivateConfigClass} from '../../common/config/private/Config';
|
||||
import {UserDTO, UserRoles} from '../../common/entities/UserDTO';
|
||||
import {NotificationManager} from '../model/NotifocationManager';
|
||||
import {Logger} from '../Logger';
|
||||
import {SharingDTO} from '../../common/entities/SharingDTO';
|
||||
import {Utils} from '../../common/Utils';
|
||||
import {LoggerRouter} from '../routes/LoggerRouter';
|
||||
import {TAGS} from '../../common/config/public/ClientConfig';
|
||||
|
||||
export class RenderingMWs {
|
||||
public static renderResult(
|
||||
@ -57,7 +58,7 @@ export class RenderingMWs {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { password, creator, ...sharing } = req.resultPipe as SharingDTO;
|
||||
const {password, creator, ...sharing} = req.resultPipe as SharingDTO;
|
||||
RenderingMWs.renderMessage(res, sharing);
|
||||
}
|
||||
|
||||
@ -107,12 +108,12 @@ export class RenderingMWs {
|
||||
const originalConf = await Config.original();
|
||||
// These are sensitive information, do not send to the client side
|
||||
originalConf.Server.sessionSecret = null;
|
||||
originalConf.Users.enforcedUsers = null;
|
||||
const message = new Message<PrivateConfigClass>(
|
||||
null,
|
||||
originalConf.toJSON({
|
||||
attachState: true,
|
||||
attachVolatile: true,
|
||||
skipTags: {secret: true} as TAGS
|
||||
}) as PrivateConfigClass
|
||||
);
|
||||
res.json(message);
|
||||
|
@ -3,6 +3,8 @@ import {ErrorCodes, ErrorDTO} from '../../../common/entities/Error';
|
||||
import {Logger} from '../../Logger';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {ConfigDiagnostics} from '../../model/diagnostics/ConfigDiagnostics';
|
||||
import {ConfigClassBuilder} from '../../../../node_modules/typeconfig/node';
|
||||
import {TAGS} from '../../../common/config/public/ClientConfig';
|
||||
|
||||
const LOG_TAG = '[SettingsMWs]';
|
||||
|
||||
@ -23,9 +25,18 @@ export class SettingsMWs {
|
||||
}
|
||||
|
||||
try {
|
||||
const settings = req.body.settings; // Top level settings JSON
|
||||
let settings = req.body.settings; // Top level settings JSON
|
||||
const settingsPath: string = req.body.settingsPath; // Name of the top level settings
|
||||
|
||||
const transformer = await Config.original();
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
transformer[settingsPath] = settings;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
settings = ConfigClassBuilder.attachPrivateInterface(transformer[settingsPath]).toJSON({
|
||||
skipTags: {secret: true} as TAGS
|
||||
});
|
||||
const original = await Config.original();
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
@ -38,7 +49,7 @@ export class SettingsMWs {
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config.toJSON({attachDescription: false}), null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
|
@ -119,16 +119,21 @@ export class SQLConnection {
|
||||
) {
|
||||
for (const uc of Config.Users.enforcedUsers) {
|
||||
const user = await userRepository.findOneBy({ name: uc.name });
|
||||
|
||||
// encrypt password and save back to the config
|
||||
if(uc.password) {
|
||||
console.log(uc.password);
|
||||
if (!uc.encryptedPassword) {
|
||||
uc.encryptedPassword = PasswordHelper.cryptPassword(uc.password);
|
||||
}
|
||||
uc.encrypted = !!uc.encryptedPassword;
|
||||
uc.password = '';
|
||||
await Config.save();
|
||||
}
|
||||
if (!user) {
|
||||
Logger.info(LOG_TAG, 'Saving enforced user: ' + uc.name);
|
||||
const a = new UserEntity();
|
||||
a.name = uc.name;
|
||||
// encrypt password and save back to the db
|
||||
if (!uc.encryptedPassword) {
|
||||
uc.encryptedPassword = PasswordHelper.cryptPassword(uc.password);
|
||||
uc.password = '';
|
||||
await Config.save();
|
||||
}
|
||||
a.password = uc.encryptedPassword;
|
||||
a.role = uc.role;
|
||||
await userRepository.save(a);
|
||||
|
@ -9,7 +9,7 @@ import {CookieNames} from '../../common/CookieNames';
|
||||
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||
import {UserDTO} from '../../common/entities/UserDTO';
|
||||
import {ServerTimeEntry} from '../middlewares/ServerTimingMWs';
|
||||
import {ClientConfig} from '../../common/config/public/ClientConfig';
|
||||
import {ClientConfig, TAGS} from '../../common/config/public/ClientConfig';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
@ -83,7 +83,11 @@ export class PublicRouter {
|
||||
res.tpl.user.csrfToken = req.csrfToken();
|
||||
}
|
||||
}
|
||||
const confCopy = Config.toJSON({attachVolatile: true, keepTags: {client: true}}) as unknown as ClientConfig;
|
||||
const confCopy = Config.toJSON({
|
||||
attachVolatile: true,
|
||||
skipTags: {secret: true} as TAGS,
|
||||
keepTags: {client: true}
|
||||
}) as unknown as ClientConfig;
|
||||
// Escaping html tags, like <script></script>
|
||||
confCopy.Server.customHTMLHead =
|
||||
confCopy.Server.customHTMLHead
|
||||
|
@ -62,7 +62,7 @@ export class Server {
|
||||
).configPath +
|
||||
':'
|
||||
);
|
||||
Logger.verbose(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
Logger.verbose(LOG_TAG, JSON.stringify(Config.toJSON({attachDescription: false}), null, '\t'));
|
||||
|
||||
this.app = express();
|
||||
|
||||
|
@ -1,26 +1,25 @@
|
||||
/* eslint-disable @typescript-eslint/no-inferrable-types */
|
||||
import 'reflect-metadata';
|
||||
import {
|
||||
JobScheduleDTO,
|
||||
JobTrigger,
|
||||
JobTriggerType,
|
||||
} from '../../entities/job/JobScheduleDTO';
|
||||
import {JobScheduleDTO, JobTrigger, JobTriggerType,} from '../../entities/job/JobScheduleDTO';
|
||||
import {
|
||||
ClientConfig,
|
||||
ClientGPXCompressingConfig, ClientMediaConfig,
|
||||
ClientMetaFileConfig, ClientPhotoConfig, ClientPhotoConvertingConfig,
|
||||
ClientGPXCompressingConfig,
|
||||
ClientMediaConfig,
|
||||
ClientMetaFileConfig,
|
||||
ClientPhotoConfig,
|
||||
ClientPhotoConvertingConfig,
|
||||
ClientServiceConfig,
|
||||
ClientSharingConfig, ClientThumbnailConfig,
|
||||
ClientUserConfig, ClientVideoConfig, ConfigPriority, MapProviders, TAGS
|
||||
ClientSharingConfig,
|
||||
ClientThumbnailConfig,
|
||||
ClientUserConfig,
|
||||
ClientVideoConfig,
|
||||
ConfigPriority,
|
||||
TAGS
|
||||
} from '../public/ClientConfig';
|
||||
import {SubConfigClass} from 'typeconfig/src/decorators/class/SubConfigClass';
|
||||
import {ConfigProperty} from 'typeconfig/src/decorators/property/ConfigPropoerty';
|
||||
import {DefaultsJobs} from '../../entities/job/JobDTO';
|
||||
import {
|
||||
SearchQueryDTO,
|
||||
SearchQueryTypes,
|
||||
TextSearch,
|
||||
} from '../../entities/SearchQueryDTO';
|
||||
import {SearchQueryDTO, SearchQueryTypes, TextSearch,} from '../../entities/SearchQueryDTO';
|
||||
import {SortingMethods} from '../../entities/SortingMethods';
|
||||
import {UserRoles} from '../../entities/UserDTO';
|
||||
|
||||
@ -163,17 +162,18 @@ export class UserConfig {
|
||||
priority: ConfigPriority.underTheHood
|
||||
},
|
||||
})
|
||||
role: UserRoles;
|
||||
role: UserRoles = UserRoles.User;
|
||||
|
||||
@ConfigProperty({
|
||||
tags:
|
||||
{
|
||||
name: $localize`Password`,
|
||||
priority: ConfigPriority.underTheHood
|
||||
priority: ConfigPriority.underTheHood,
|
||||
relevant: (c: UserConfig) => !c.encrypted
|
||||
},
|
||||
description: $localize`Unencrypted, temporary password. App will encrypt it and delete this.`
|
||||
})
|
||||
password: string = '';
|
||||
password: string;
|
||||
@ConfigProperty({
|
||||
tags:
|
||||
{
|
||||
@ -184,10 +184,25 @@ export class UserConfig {
|
||||
})
|
||||
encryptedPassword: string | undefined;
|
||||
|
||||
constructor(name: string, password: string, role: UserRoles) {
|
||||
this.name = name;
|
||||
this.role = role;
|
||||
this.password = password;
|
||||
@ConfigProperty({
|
||||
tags:
|
||||
{
|
||||
priority: ConfigPriority.underTheHood,
|
||||
relevant: () => false // never render this on UI. Only used to indicate that encryption is done.
|
||||
} as TAGS,
|
||||
})
|
||||
encrypted: boolean;
|
||||
|
||||
constructor(name?: string, password?: string, role?: UserRoles) {
|
||||
if (name) {
|
||||
this.name = name;
|
||||
}
|
||||
if (typeof role !== 'undefined') {
|
||||
this.role = role;
|
||||
}
|
||||
if (password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,7 +210,7 @@ export class UserConfig {
|
||||
export class ServerDataBaseConfig {
|
||||
@ConfigProperty<DatabaseType, ServerConfig>({
|
||||
type: DatabaseType,
|
||||
onNewValue: (value: DatabaseType, config: ServerConfig) => {
|
||||
onNewValue: (value, config) => {
|
||||
if (config && value === DatabaseType.memory) {
|
||||
config.Search.enabled = false;
|
||||
config.Sharing.enabled = false;
|
||||
@ -248,8 +263,9 @@ export class ServerUserConfig extends ClientUserConfig {
|
||||
tags:
|
||||
{
|
||||
name: $localize`Enforced users`,
|
||||
priority: ConfigPriority.underTheHood
|
||||
},
|
||||
priority: ConfigPriority.underTheHood,
|
||||
uiOptional: true
|
||||
} as TAGS,
|
||||
description: $localize`Creates these users in the DB if they do not exist. If a user with this name exist, it won't be overwritten, even if the role is different.`,
|
||||
})
|
||||
enforcedUsers: UserConfig[] = [];
|
||||
|
@ -724,7 +724,7 @@ export class ClientServiceConfig {
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Page title`
|
||||
}
|
||||
} as TAGS
|
||||
})
|
||||
applicationTitle: string = 'PiGallery 2';
|
||||
|
||||
@ -732,6 +732,7 @@ export class ClientServiceConfig {
|
||||
description: $localize`If you access the page form local network its good to know the public url for creating sharing link.`,
|
||||
tags: {
|
||||
name: $localize`Page public url`,
|
||||
uiOptional: true
|
||||
}
|
||||
})
|
||||
publicUrl: string = '';
|
||||
@ -741,7 +742,8 @@ export class ClientServiceConfig {
|
||||
tags: {
|
||||
name: $localize`Url Base`,
|
||||
hint: '/myGallery',
|
||||
priority: ConfigPriority.advanced
|
||||
priority: ConfigPriority.advanced,
|
||||
uiOptional: true
|
||||
}
|
||||
})
|
||||
urlBase: string = '';
|
||||
@ -763,7 +765,8 @@ export class ClientServiceConfig {
|
||||
tags: {
|
||||
name: $localize`Custom HTML Head`,
|
||||
priority: ConfigPriority.advanced,
|
||||
githubIssue: 404
|
||||
githubIssue: 404,
|
||||
uiOptional: true
|
||||
}
|
||||
})
|
||||
customHTMLHead: string = '';
|
||||
@ -772,7 +775,12 @@ export class ClientServiceConfig {
|
||||
@SubConfigClass({tags: {client: true}})
|
||||
export class ClientUserConfig {
|
||||
|
||||
@ConfigProperty({
|
||||
@ConfigProperty<boolean, ClientConfig>({
|
||||
onNewValue: (value, config) => {
|
||||
if (config && value === false) {
|
||||
config.Sharing.enabled = false;
|
||||
}
|
||||
},
|
||||
tags: {
|
||||
name: $localize`Password protection`,
|
||||
priority: ConfigPriority.advanced,
|
||||
|
@ -99,6 +99,7 @@ import {GalleryFilterComponent} from './ui/gallery/filter/filter.gallery.compone
|
||||
import {GallerySortingService} from './ui/gallery/navigator/sorting.service';
|
||||
import {FilterService} from './ui/gallery/filter/filter.service';
|
||||
import {TemplateComponent} from './ui/settings/template/template.component';
|
||||
import {AbstractSettingsService} from './ui/settings/_abstract/abstract.settings.service';
|
||||
|
||||
@Injectable()
|
||||
export class MyHammerConfig extends HammerGestureConfig {
|
||||
@ -216,24 +217,24 @@ Marker.prototype.options.icon = iconDefault;
|
||||
// Settings
|
||||
SettingsEntryComponent,
|
||||
TemplateComponent,
|
||||
/* UserMangerSettingsComponent,
|
||||
DatabaseSettingsComponent,
|
||||
MapSettingsComponent,
|
||||
ThumbnailSettingsComponent,
|
||||
VideoSettingsComponent,
|
||||
PhotoSettingsComponent,
|
||||
MetaFileSettingsComponent,
|
||||
SearchSettingsComponent,
|
||||
ShareSettingsComponent,
|
||||
RandomPhotoSettingsComponent,
|
||||
FacesSettingsComponent,
|
||||
AlbumsSettingsComponent,
|
||||
OtherSettingsComponent,
|
||||
IndexingSettingsComponent,
|
||||
JobsSettingsComponent,
|
||||
JobProgressComponent,
|
||||
JobButtonComponent,
|
||||
PreviewSettingsComponent,*/
|
||||
/* UserMangerSettingsComponent,
|
||||
DatabaseSettingsComponent,
|
||||
MapSettingsComponent,
|
||||
ThumbnailSettingsComponent,
|
||||
VideoSettingsComponent,
|
||||
PhotoSettingsComponent,
|
||||
MetaFileSettingsComponent,
|
||||
SearchSettingsComponent,
|
||||
ShareSettingsComponent,
|
||||
RandomPhotoSettingsComponent,
|
||||
FacesSettingsComponent,
|
||||
AlbumsSettingsComponent,
|
||||
OtherSettingsComponent,
|
||||
IndexingSettingsComponent,
|
||||
JobsSettingsComponent,
|
||||
JobProgressComponent,
|
||||
JobButtonComponent,
|
||||
PreviewSettingsComponent,*/
|
||||
|
||||
// Pipes
|
||||
StringifyRole,
|
||||
@ -281,6 +282,7 @@ Marker.prototype.options.icon = iconDefault;
|
||||
ScheduledJobsService,
|
||||
BackendtextService,
|
||||
CookieService,
|
||||
AbstractSettingsService
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
|
@ -25,6 +25,7 @@ import {IConfigClassPrivate} from '../../../../../../node_modules/typeconfig/src
|
||||
import {IPropertyMetadata} from '../../../../../../node_modules/typeconfig/src/decorators/property/IPropertyState';
|
||||
import {IWebConfigClass, IWebConfigClassPrivate} from '../../../../../../node_modules/typeconfig/src/decorators/class/IWebConfigClass';
|
||||
import {WebConfigClassBuilder} from '../../../../../../node_modules/typeconfig/src/decorators/builders/WebConfigClassBuilder';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
|
||||
interface ConfigState<T = unknown> {
|
||||
value: T;
|
||||
@ -59,17 +60,14 @@ export interface RecursiveState extends ConfigState {
|
||||
|
||||
@Directive()
|
||||
export abstract class SettingsComponentDirective<
|
||||
T extends RecursiveState,
|
||||
S extends AbstractSettingsService<T> = AbstractSettingsService<T>
|
||||
> implements OnInit, OnDestroy, OnChanges, ISettingsComponent {
|
||||
@Input()
|
||||
public configPriority = ConfigPriority.basic;
|
||||
T extends RecursiveState> implements OnInit, OnDestroy, ISettingsComponent {
|
||||
|
||||
@Input() icon: string;
|
||||
@Input() ConfigPath: string;
|
||||
|
||||
@ViewChild('settingsForm', {static: true})
|
||||
form: FormControl;
|
||||
|
||||
@Output()
|
||||
hasAvailableSettings = true;
|
||||
|
||||
public inProgress = false;
|
||||
public error: string = null;
|
||||
@ -82,10 +80,9 @@ export abstract class SettingsComponentDirective<
|
||||
|
||||
protected constructor(
|
||||
protected name: string,
|
||||
public icon: string,
|
||||
protected authService: AuthenticationService,
|
||||
private navigation: NavigationService,
|
||||
public settingsService: S,
|
||||
public settingsService: AbstractSettingsService,
|
||||
protected notification: NotificationService,
|
||||
protected globalSettingsService: SettingsService,
|
||||
sliceFN?: (s: IWebConfigClassPrivate<TAGS> & WebConfig) => T
|
||||
@ -175,8 +172,6 @@ export abstract class SettingsComponentDirective<
|
||||
}
|
||||
};
|
||||
instrument(this.states, null);
|
||||
|
||||
this.ngOnChanges();
|
||||
};
|
||||
|
||||
onOptionChange = () => {
|
||||
@ -224,9 +219,6 @@ export abstract class SettingsComponentDirective<
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.subscription != null) {
|
||||
this.subscription.unsubscribe();
|
||||
@ -248,7 +240,7 @@ export abstract class SettingsComponentDirective<
|
||||
this.inProgress = true;
|
||||
this.error = '';
|
||||
try {
|
||||
await this.settingsService.updateSettings(this.stateToSettings());
|
||||
await this.settingsService.updateSettings(this.stateToSettings(), this.ConfigPath);
|
||||
await this.getSettings();
|
||||
this.notification.success(
|
||||
this.Name + ' ' + $localize`settings saved`,
|
||||
|
@ -1,9 +1,14 @@
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { SettingsService } from '../settings.service';
|
||||
import { WebConfig } from '../../../../../common/config/private/WebConfig';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {WebConfig} from '../../../../../common/config/private/WebConfig';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {Injectable} from '@angular/core';
|
||||
|
||||
export abstract class AbstractSettingsService<T> {
|
||||
protected constructor(public settingsService: SettingsService) {}
|
||||
@Injectable()
|
||||
export class AbstractSettingsService {
|
||||
constructor(public settingsService: SettingsService,
|
||||
private networkService: NetworkService) {
|
||||
}
|
||||
|
||||
get Settings(): BehaviorSubject<WebConfig> {
|
||||
return this.settingsService.settings;
|
||||
@ -13,6 +18,7 @@ export abstract class AbstractSettingsService<T> {
|
||||
return this.settingsService.getSettings();
|
||||
}
|
||||
|
||||
|
||||
abstract updateSettings(settings: T): Promise<void>;
|
||||
public updateSettings(settings: Record<string, any>, settingsPath: string): Promise<void> {
|
||||
return this.networkService.putJson('/settings', {settings, settingsPath});
|
||||
}
|
||||
}
|
||||
|
@ -186,8 +186,8 @@
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="ArrayType === 'UserConfig'">
|
||||
<div class="container">
|
||||
<div class="row mt-1 mb-1 bg-light" *ngFor="let item of state.value; let i = index">
|
||||
<div class="container ps-0 pe-0">
|
||||
<div class="row ms-0 me-0 mt-1 mb-1 bg-light" *ngFor="let item of state.value; let i = index">
|
||||
<div class="col ps-0">
|
||||
<input type="text" class="form-control"
|
||||
placeholder="Name"
|
||||
@ -208,7 +208,9 @@
|
||||
</select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<input type="password" class="form-control"
|
||||
<input *ngIf="!item.encrypted"
|
||||
type="password"
|
||||
class="form-control"
|
||||
[(ngModel)]="item.password"
|
||||
(ngModelChange)="onChange($event)"
|
||||
[name]="'item_p_'+idName+i"
|
||||
@ -216,15 +218,16 @@
|
||||
required>
|
||||
</div>
|
||||
<div class="col-1 pe-0">
|
||||
<button [disabled]="state.value.length == 1" (click)="remove(i)"
|
||||
[ngClass]="state.value.length > 1? 'btn-danger':'btn-secondary'"
|
||||
<button [disabled]="(state.value.length == 1 && !state.tags.uiOptional)"
|
||||
(click)="remove(i)"
|
||||
[ngClass]="(state.value.length > 1 || state.tags.uiOptional)? 'btn-danger':'btn-secondary'"
|
||||
class="btn float-end">
|
||||
<span class="oi oi-trash" aria-hidden="true" aria-label="Delete"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row me-0">
|
||||
<div class="col pe-0">
|
||||
<button class="btn btn-primary float-end"
|
||||
(click)="AddNew()" i18n>+ Add Link
|
||||
|
@ -316,6 +316,7 @@ export class SettingsEntryComponent
|
||||
|
||||
remove(i: number): void {
|
||||
(this.state.value as unknown[]).splice(i, 1);
|
||||
this.onChange(null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,7 +37,7 @@
|
||||
{{Name}} <span i18n>config is not supported with these settings.</span>
|
||||
</div>
|
||||
<button class="btn btn-success float-end"
|
||||
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
||||
[disabled]="settingsForm.form.invalid || !changed || inProgress"
|
||||
(click)="save()" i18n>Save
|
||||
</button>
|
||||
<button class="btn btn-secondary float-end"
|
||||
|
@ -1,39 +1,31 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {MapSettingsService} from '../map/map.settings.service';
|
||||
import {TemplateSettingsService} from './template.settings.service';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {SettingsComponentDirective} from '../_abstract/abstract.settings.component';
|
||||
import {ClientMapConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {WebConfig} from '../../../../../common/config/private/WebConfig';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-template',
|
||||
templateUrl: './template.component.html',
|
||||
styleUrls: ['./template.component.css',
|
||||
'../_abstract/abstract.settings.component.css'],
|
||||
providers: [TemplateSettingsService],
|
||||
'../_abstract/abstract.settings.component.css']
|
||||
})
|
||||
export class TemplateComponent extends SettingsComponentDirective<any> implements OnInit {
|
||||
|
||||
@Input() ConfigPath: keyof ServerConfig;
|
||||
@Input() icon: string;
|
||||
public configKeys: string[] = [];
|
||||
|
||||
constructor(
|
||||
authService: AuthenticationService,
|
||||
navigation: NavigationService,
|
||||
settingsService: TemplateSettingsService,
|
||||
notification: NotificationService,
|
||||
settingsService: AbstractSettingsService,
|
||||
globalSettingsService: SettingsService
|
||||
) {
|
||||
super(
|
||||
`Template`,
|
||||
'',
|
||||
authService,
|
||||
navigation,
|
||||
settingsService,
|
||||
|
@ -1,23 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { NetworkService } from '../../../model/network/network.service';
|
||||
import { SettingsService } from '../settings.service';
|
||||
import { AbstractSettingsService } from '../_abstract/abstract.settings.service';
|
||||
import { ClientMapConfig } from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Injectable()
|
||||
export class TemplateSettingsService extends AbstractSettingsService<any> {
|
||||
constructor(
|
||||
private networkService: NetworkService,
|
||||
settingsService: SettingsService
|
||||
) {
|
||||
super(settingsService);
|
||||
}
|
||||
|
||||
hasAvailableSettings(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
public updateSettings(settings: ClientMapConfig): Promise<void> {
|
||||
return this.networkService.putJson('/settings', { settings });
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user