mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-01-10 04:07:35 +02:00
Improving settings UI #569
This commit is contained in:
parent
36b0a216d6
commit
2350bc780d
@ -882,6 +882,7 @@ export class ServerMediaConfig extends ClientMediaConfig {
|
|||||||
@ConfigProperty({
|
@ConfigProperty({
|
||||||
tags: {
|
tags: {
|
||||||
name: $localize`Video`,
|
name: $localize`Video`,
|
||||||
|
uiIcon: 'video',
|
||||||
priority: ConfigPriority.advanced,
|
priority: ConfigPriority.advanced,
|
||||||
uiJob: [
|
uiJob: [
|
||||||
{
|
{
|
||||||
@ -895,6 +896,7 @@ export class ServerMediaConfig extends ClientMediaConfig {
|
|||||||
@ConfigProperty({
|
@ConfigProperty({
|
||||||
tags: {
|
tags: {
|
||||||
name: $localize`Photo`,
|
name: $localize`Photo`,
|
||||||
|
uiIcon: 'camera-slr',
|
||||||
priority: ConfigPriority.advanced,
|
priority: ConfigPriority.advanced,
|
||||||
uiJob: [
|
uiJob: [
|
||||||
{
|
{
|
||||||
@ -907,6 +909,7 @@ export class ServerMediaConfig extends ClientMediaConfig {
|
|||||||
@ConfigProperty({
|
@ConfigProperty({
|
||||||
tags: {
|
tags: {
|
||||||
name: $localize`Thumbnail`,
|
name: $localize`Thumbnail`,
|
||||||
|
uiIcon: 'grid-three-up',
|
||||||
priority: ConfigPriority.advanced,
|
priority: ConfigPriority.advanced,
|
||||||
uiJob: [{job: DefaultsJobs[DefaultsJobs['Thumbnail Generation']]}]
|
uiJob: [{job: DefaultsJobs[DefaultsJobs['Thumbnail Generation']]}]
|
||||||
} as TAGS
|
} as TAGS
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { backendText } from '../../BackendTexts';
|
import {backendText} from '../../BackendTexts';
|
||||||
|
|
||||||
export type fieldType = 'string' | 'number' | 'boolean' | 'number-array';
|
export type fieldType = 'string' | 'number' | 'boolean' | 'number-array';
|
||||||
|
|
||||||
@ -29,6 +29,7 @@ export interface JobDTO {
|
|||||||
|
|
||||||
export const JobDTOUtils = {
|
export const JobDTOUtils = {
|
||||||
getHashName: (jobName: string, config: any = {}) => {
|
getHashName: (jobName: string, config: any = {}) => {
|
||||||
return jobName + '-' + JSON.stringify(config);
|
const sorted = Object.keys(config).sort().reduce((ret, key) => `${ret},${key}:${JSON.stringify(config[key])}`, '');
|
||||||
|
return jobName + '-' + JSON.stringify(sorted);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -73,12 +73,21 @@
|
|||||||
<div class="card-body text-md-start text-center align-content-md-start align-content-center">
|
<div class="card-body text-md-start text-center align-content-md-start align-content-center">
|
||||||
<h5 i18n="title of left card in settings page that contains settings contents" class="card-title">
|
<h5 i18n="title of left card in settings page that contains settings contents" class="card-title">
|
||||||
Menu</h5>
|
Menu</h5>
|
||||||
<button class="btn btn-link nav-link text-start py-md-1 px-md-0"
|
<div class="py-md-1 px-md-0"
|
||||||
*ngFor="let s of contents; let i=index;"
|
*ngFor="let s of contents;"
|
||||||
(click)="scrollTo(i)"
|
[hidden]="!s.HasAvailableSettings">
|
||||||
[hidden]="!s.HasAvailableSettings">
|
<button class="btn btn-link nav-link text-start p-0"
|
||||||
<span class="oi oi-{{s.icon}}"></span> {{s.Name}}
|
(click)="viewportScroller.scrollToAnchor(s.ConfigPath)"
|
||||||
</button>
|
>
|
||||||
|
<span class="oi oi-{{s.icon}}"></span> {{s.Name}}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-link nav-link text-start ms-3 p-0"
|
||||||
|
*ngFor="let n of s.nestedConfigs;"
|
||||||
|
[hidden]="!n.visible()"
|
||||||
|
(click)="viewportScroller.scrollToAnchor(n.id)">
|
||||||
|
<span class="oi oi-{{n.icon}}"></span> {{n.name}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -90,6 +99,7 @@
|
|||||||
#setting
|
#setting
|
||||||
#tmpl
|
#tmpl
|
||||||
[ConfigPath]="cp"
|
[ConfigPath]="cp"
|
||||||
|
[enableNesting]="cp=='Media'"
|
||||||
[hidden]="!tmpl.HasAvailableSettings">
|
[hidden]="!tmpl.HasAvailableSettings">
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngIf="cp=='Indexing'">
|
*ngIf="cp=='Indexing'">
|
||||||
|
@ -4,7 +4,7 @@ import {UserRoles} from '../../../../common/entities/UserDTO';
|
|||||||
import {NotificationService} from '../../model/notification.service';
|
import {NotificationService} from '../../model/notification.service';
|
||||||
import {NotificationType} from '../../../../common/entities/NotificationDTO';
|
import {NotificationType} from '../../../../common/entities/NotificationDTO';
|
||||||
import {NavigationService} from '../../model/navigation.service';
|
import {NavigationService} from '../../model/navigation.service';
|
||||||
import {PageHelper} from '../../model/page.helper';
|
import {ViewportScroller} from '@angular/common';
|
||||||
import {SettingsService} from '../settings/settings.service';
|
import {SettingsService} from '../settings/settings.service';
|
||||||
import {ConfigPriority} from '../../../../common/config/public/ClientConfig';
|
import {ConfigPriority} from '../../../../common/config/public/ClientConfig';
|
||||||
import {WebConfig} from '../../../../common/config/private/WebConfig';
|
import {WebConfig} from '../../../../common/config/private/WebConfig';
|
||||||
@ -29,6 +29,7 @@ export class AdminComponent implements OnInit, AfterViewInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private authService: AuthenticationService,
|
private authService: AuthenticationService,
|
||||||
private navigation: NavigationService,
|
private navigation: NavigationService,
|
||||||
|
public viewportScroller: ViewportScroller,
|
||||||
public notificationService: NotificationService,
|
public notificationService: NotificationService,
|
||||||
public settingsService: SettingsService,
|
public settingsService: SettingsService,
|
||||||
) {
|
) {
|
||||||
@ -42,12 +43,6 @@ export class AdminComponent implements OnInit, AfterViewInit {
|
|||||||
setTimeout(() => (this.contents = this.settingsComponents.toArray()), 0);
|
setTimeout(() => (this.contents = this.settingsComponents.toArray()), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollTo(i: number): void {
|
|
||||||
PageHelper.ScrollY =
|
|
||||||
this.settingsComponentsElemRef
|
|
||||||
.toArray()[i].nativeElement.getBoundingClientRect().top + PageHelper.ScrollY;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (
|
if (
|
||||||
!this.authService.isAuthenticated() ||
|
!this.authService.isAuthenticated() ||
|
||||||
|
@ -2,5 +2,7 @@ export interface ISettingsComponent {
|
|||||||
HasAvailableSettings: boolean;
|
HasAvailableSettings: boolean;
|
||||||
Name: string;
|
Name: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
|
ConfigPath: string;
|
||||||
Changed: boolean;
|
Changed: boolean;
|
||||||
|
nestedConfigs: { id: string, name: string, visible: () => boolean, icon: string }[];
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<form #settingsForm="ngForm" class="form-horizontal">
|
<form #settingsForm="ngForm" class="form-horizontal" [id]="ConfigPath">
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<h5 class="card-header">
|
<h5 class="card-header">
|
||||||
<span class="oi oi-{{icon}}"></span> {{Name}}
|
<span class="oi oi-{{icon}}"></span> {{Name}}
|
||||||
@ -24,7 +24,7 @@
|
|||||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||||
<ng-container *ngIf="states.value.enabled !== false">
|
<ng-container *ngIf="states.value.enabled !== false">
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngTemplateOutlet="Recursion; context:{ rStates: states,skipEnabled:true,confPath:ConfigPath,skipJobs:true }"
|
*ngTemplateOutlet="Recursion; context:{ rStates: states,topLevel:true,confPath:ConfigPath,skipJobs:true }"
|
||||||
></ng-container>
|
></ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
@ -32,7 +32,7 @@
|
|||||||
*ngIf="states.value.enabled === false">
|
*ngIf="states.value.enabled === false">
|
||||||
{{Name}} <span i18n>config is not supported with these settings.</span>
|
{{Name}} <span i18n>config is not supported with these settings.</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row mt-2">
|
||||||
<div class="col" *ngIf="states.tags?.uiJob && !states.tags?.uiJob[0].description">
|
<div class="col" *ngIf="states.tags?.uiJob && !states.tags?.uiJob[0].description">
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngTemplateOutlet="JobTemplate; context:{ uiJob: states.tags?.uiJob }"
|
*ngTemplateOutlet="JobTemplate; context:{ uiJob: states.tags?.uiJob }"
|
||||||
@ -67,7 +67,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-template #Recursion let-rStates="rStates" let-skipEnabled="skipEnabled" let-skipJobs="skipJobs"
|
<ng-template #Recursion let-rStates="rStates" let-topLevel="topLevel" let-skipJobs="skipJobs"
|
||||||
let-confPath="confPath">
|
let-confPath="confPath">
|
||||||
<div class="alert alert-secondary" role="alert" *ngIf="rStates.description">
|
<div class="alert alert-secondary" role="alert" *ngIf="rStates.description">
|
||||||
{{rStates.description}}
|
{{rStates.description}}
|
||||||
@ -75,24 +75,34 @@
|
|||||||
<ng-container *ngFor="let ck of getKeys(rStates)">
|
<ng-container *ngFor="let ck of getKeys(rStates)">
|
||||||
<ng-container *ngIf="!(rStates.value.__state[ck].shouldHide && rStates.value.__state[ck].shouldHide())">
|
<ng-container *ngIf="!(rStates.value.__state[ck].shouldHide && rStates.value.__state[ck].shouldHide())">
|
||||||
<app-settings-entry
|
<app-settings-entry
|
||||||
*ngIf="(ck!=='enabled' || !skipEnabled) && !rStates.value.__state[ck].isConfigType"
|
*ngIf="(ck!=='enabled' || !topLevel) && !rStates.value.__state[ck].isConfigType"
|
||||||
[name]="confPath+'_'+ck"
|
[name]="confPath+'_'+ck"
|
||||||
[ngModel]="rStates?.value.__state[ck]">
|
[ngModel]="rStates?.value.__state[ck]">
|
||||||
</app-settings-entry>
|
</app-settings-entry>
|
||||||
<ng-container *ngIf="rStates.value.__state[ck].isConfigType">
|
<ng-container *ngIf="rStates.value.__state[ck].isConfigType">
|
||||||
<div class="row mt-2">
|
<div class="card mt-2 mb-2" *ngIf="topLevel && enableNesting" [id]="ConfigPath+'.'+ck">
|
||||||
<div class="col-auto">
|
<div class="card-body">
|
||||||
<h5>{{rStates?.value.__state[ck].tags?.name || ck}}</h5>
|
<h5 class="card-title"><span class="oi oi-{{rStates?.value.__state[ck].tags?.uiIcon}}"></span> {{rStates?.value.__state[ck].tags?.name || ck}}</h5>
|
||||||
</div>
|
<ng-container
|
||||||
<div class="col">
|
*ngTemplateOutlet="Recursion; context:{ rStates: rStates.value.__state[ck], confPath:confPath+'.'+ck }"
|
||||||
<hr/>
|
></ng-container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2">
|
<ng-container *ngIf="!topLevel || !enableNesting">
|
||||||
<ng-container
|
<div class="row mt-2">
|
||||||
*ngTemplateOutlet="Recursion; context:{ rStates: rStates.value.__state[ck], confPath:confPath+'.'+ck }"
|
<div class="col-auto">
|
||||||
></ng-container>
|
<h5>{{rStates?.value.__state[ck].tags?.name || ck}}</h5>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2">
|
||||||
|
<ng-container
|
||||||
|
*ngTemplateOutlet="Recursion; context:{ rStates: rStates.value.__state[ck], confPath:confPath+'.'+ck }"
|
||||||
|
></ng-container>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -59,6 +59,8 @@ export class TemplateComponent implements OnInit, OnChanges, OnDestroy, ISetting
|
|||||||
|
|
||||||
public icon: string;
|
public icon: string;
|
||||||
@Input() ConfigPath: string;
|
@Input() ConfigPath: string;
|
||||||
|
@Input() enableNesting: boolean;
|
||||||
|
nestedConfigs: { id: string, name: string, visible: () => boolean,icon:string }[] = [];
|
||||||
|
|
||||||
@ViewChild('settingsForm', {static: true})
|
@ViewChild('settingsForm', {static: true})
|
||||||
form: FormControl;
|
form: FormControl;
|
||||||
@ -90,6 +92,19 @@ export class TemplateComponent implements OnInit, OnChanges, OnDestroy, ISetting
|
|||||||
this.setSliceFN(c => c.__state[this.ConfigPath]);
|
this.setSliceFN(c => c.__state[this.ConfigPath]);
|
||||||
}
|
}
|
||||||
this.name = this.states.tags?.name || this.ConfigPath;
|
this.name = this.states.tags?.name || this.ConfigPath;
|
||||||
|
this.nestedConfigs = [];
|
||||||
|
if (this.enableNesting) {
|
||||||
|
for (const key of this.getKeys(this.states)) {
|
||||||
|
if (this.states.value.__state[key].isConfigType) {
|
||||||
|
this.nestedConfigs.push({
|
||||||
|
id: this.ConfigPath + '.' + key,
|
||||||
|
name: this.states?.value.__state[key].tags?.name,
|
||||||
|
icon: this.states?.value.__state[key].tags?.uiIcon,
|
||||||
|
visible: () => !(this.states.value.__state[key].shouldHide && this.states.value.__state[key].shouldHide())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
Loading…
Reference in New Issue
Block a user