1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00

Add compact settings view #587

This commit is contained in:
Patrik J. Braun 2023-08-05 15:55:52 +02:00
parent d822e7b223
commit de30430e63
16 changed files with 104 additions and 46 deletions

View File

@ -2,4 +2,5 @@ export class CookieNames {
public static lang = 'pigallery2-lang';
public static session = 'pigallery2-session';
public static configPriority = 'config-priority';
public static configStyle = 'config-style';
}

View File

@ -319,7 +319,7 @@ export class ServerThumbnailConfig extends ClientThumbnailConfig {
type: 'boolean',
tags:
{
name: $localize`Use chroma subsampling.`,
name: $localize`Use chroma subsampling`,
priority: ConfigPriority.underTheHood
},
description: $localize`Use high quality chroma subsampling in webp. See: https://sharp.pixelplumbing.com/api-output#webp.`

View File

@ -21,7 +21,7 @@ export enum MapProviders {
}
export enum ConfigPriority {
basic = 0, advanced, underTheHood
basic = 1, advanced, underTheHood
}

View File

@ -105,7 +105,7 @@ import {SettingsEntryComponent} from './ui/settings/template/settings-entry/sett
import {UsersComponent} from './ui/settings/users/users.component';
import {SharingsListComponent} from './ui/settings/sharings-list/sharings-list.component';
import {ThemeService} from './model/theme.service';
import {StringifyConfigPriority} from './pipes/StringifyConfigPriority';
import {StringifyEnum} from './pipes/StringifyEnum';
import {StringifySearchType} from './pipes/StringifySearchType';
import {MarkerFactory} from './ui/gallery/map/MarkerFactory';
@ -224,7 +224,7 @@ Marker.prototype.options.icon = MarkerFactory.defIcon;
GPXFilesFilterPipe,
MDFilesFilterPipe,
StringifySearchQuery,
StringifyConfigPriority,
StringifyEnum,
StringifySearchType,
FileDTOToPathPipe,
PhotoFilterPipe,

View File

@ -1,13 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
import { ConfigPriority } from '../../../common/config/public/ClientConfig';
import { SortingMethods } from '../../../common/entities/SortingMethods';
import {EnumTranslations} from '../ui/EnumTranslations';
@Pipe({ name: 'stringifyConfigPriority' })
export class StringifyConfigPriority implements PipeTransform {
transform(method: ConfigPriority): string {
return EnumTranslations[ConfigPriority[method]];
}
}

View File

@ -0,0 +1,12 @@
import {Pipe, PipeTransform} from '@angular/core';
import {ConfigPriority} from '../../../common/config/public/ClientConfig';
import {EnumTranslations} from '../ui/EnumTranslations';
@Pipe({name: 'stringifyEnum'})
export class StringifyEnum implements PipeTransform {
transform(name: string): string {
return EnumTranslations[name];
}
}

View File

@ -3,6 +3,7 @@ import {ConfigPriority, MapProviders, NavigationLinkTypes} from '../../../common
import {ReIndexingSensitivity} from '../../../common/config/private/PrivateConfig';
import {SortingMethods} from '../../../common/entities/SortingMethods';
import {SearchQueryTypes} from '../../../common/entities/SearchQueryDTO';
import {ConfigStyle} from './settings/settings.service';
export const EnumTranslations: Record<string, string> = {};
export const enumToTranslatedArray = (EnumType: any): { key: number; value: string }[] => {
@ -26,6 +27,10 @@ EnumTranslations[ConfigPriority[ConfigPriority.basic]] = $localize`Basic`;
EnumTranslations[ConfigPriority[ConfigPriority.advanced]] = $localize`Advanced`;
EnumTranslations[ConfigPriority[ConfigPriority.underTheHood]] = $localize`Under the hood`;
EnumTranslations[ConfigStyle[ConfigStyle.full]] = $localize`Full`;
EnumTranslations[ConfigStyle[ConfigStyle.compact]] = $localize`Compact`;
EnumTranslations[MapProviders[MapProviders.Custom]] = $localize`Custom`;
EnumTranslations[MapProviders[MapProviders.OpenStreetMap]] = $localize`OpenStreetMap`;
EnumTranslations[MapProviders[MapProviders.Mapbox]] = $localize`Mapbox`;

View File

@ -36,7 +36,7 @@
</a>
</div>
<div class="mb-1">
<label class="control-label align-self-end me-2" for="config-priority" i18n>Mode</label>
<label class="control-label align-self-end me-2" for="config-priority" i18n>Mode:</label>
<div class="btn-group" dropdown #dropdown="bs-dropdown" placement="bottom right">
<button type="button"
dropdownToggle
@ -46,12 +46,29 @@
[class.btn-warning]="settingsService.configPriority === ConfigPriority.advanced"
[class.btn-danger]="settingsService.configPriority === ConfigPriority.underTheHood"
data-bs-toggle="dropdown" aria-expanded="false">
{{settingsService.configPriority | stringifyConfigPriority}}
{{ConfigPriority[settingsService.configPriority] | stringifyEnum}}
</button>
<ul class="dropdown-menu dropdown-menu-right" *dropdownMenu>
<li *ngFor="let cp of configPriorities">
<button class="dropdown-item"
(click)="settingsService.configPriority = cp.key; settingsService.configPriorityChanged()">{{cp.value}}</button>
(click)="settingsService.configPriority = cp.key; settingsService.configSetupChanged()">{{cp.value}}</button>
</li>
</ul>
</div>
<div class="ms-2 btn-group" dropdown #dropdown="bs-dropdown" placement="bottom right">
<button type="button"
dropdownToggle
id="config-style"
class="btn dropdown-toggle"
[class.btn-secondary]="settingsService.configStyle == ConfigStyle.full"
[class.btn-primary]="settingsService.configStyle == ConfigStyle.compact"
data-bs-toggle="dropdown" aria-expanded="false">
{{ConfigStyle[settingsService.configStyle] | stringifyEnum}}
</button>
<ul class="dropdown-menu dropdown-menu-right" *dropdownMenu>
<li *ngFor="let cp of configStyles">
<button class="dropdown-item"
(click)="settingsService.configStyle = cp.key; settingsService.configSetupChanged()">{{cp.value}}</button>
</li>
</ul>
</div>

View File

@ -5,7 +5,7 @@ import {NotificationService} from '../../model/notification.service';
import {NotificationType} from '../../../../common/entities/NotificationDTO';
import {NavigationService} from '../../model/navigation.service';
import {ViewportScroller} from '@angular/common';
import {SettingsService} from '../settings/settings.service';
import {ConfigStyle, SettingsService} from '../settings/settings.service';
import {ConfigPriority} from '../../../../common/config/public/ClientConfig';
import {WebConfig} from '../../../../common/config/private/WebConfig';
import {ISettingsComponent} from '../settings/template/ISettingsComponent';
@ -24,7 +24,9 @@ export class AdminComponent implements OnInit, AfterViewInit {
settingsComponentsElemRef: QueryList<ElementRef>;
contents: ISettingsComponent[] = [];
configPriorities: { key: number; value: string; }[];
configStyles: { key: number; value: string; }[];
public readonly ConfigPriority = ConfigPriority;
public readonly ConfigStyle = ConfigStyle;
public readonly configPaths: string[] = [];
constructor(
@ -36,6 +38,7 @@ export class AdminComponent implements OnInit, AfterViewInit {
private piTitleService: PiTitleService
) {
this.configPriorities = enumToTranslatedArray(ConfigPriority);
this.configStyles = enumToTranslatedArray(ConfigStyle);
const wc = WebConfigClassBuilder.attachPrivateInterface(new WebConfig());
this.configPaths = Object.keys(wc.State)
.filter(s => !wc.__state[s].volatile);

View File

@ -12,9 +12,16 @@ import {StatisticDTO} from '../../../../common/entities/settings/StatisticDTO';
import {ScheduledJobsService} from './scheduled-jobs.service';
import {IWebConfigClassPrivate} from '../../../../../node_modules/typeconfig/src/decorators/class/IWebConfigClass';
export enum ConfigStyle {
full = 1, compact
}
@Injectable()
export class SettingsService {
public configPriority = ConfigPriority.basic;
public configStyle = ConfigStyle.full;
public settings: BehaviorSubject<IWebConfigClassPrivate<TAGS> & WebConfig>;
private fetchingSettings = false;
public statistic: BehaviorSubject<StatisticDTO>;
@ -30,6 +37,10 @@ export class SettingsService {
this.configPriority =
parseInt(this.cookieService.get(CookieNames.configPriority));
}
if (this.cookieService.check(CookieNames.configStyle)) {
this.configStyle =
parseInt(this.cookieService.get(CookieNames.configStyle));
}
this.settings.pipe(first()).subscribe(() => {
@ -68,13 +79,19 @@ export class SettingsService {
return this.networkService.putJson('/settings', {settings, settingsPath});
}
configPriorityChanged(): void {
configSetupChanged(): void {
// save it for some years
this.cookieService.set(
CookieNames.configPriority,
this.configPriority.toString(),
365 * 50
);
// save it for some years
this.cookieService.set(
CookieNames.configStyle,
this.configStyle.toString(),
365 * 50
);
}
async loadStatistic(): Promise<void> {

View File

@ -5,7 +5,8 @@
</ng-template>
<ng-container *ngIf="state">
<div class="mb-3 row"
<div class="mb-1 row"
[class.mb-3]="settingsService.configStyle == ConfigStyle.full"
[class.changed-settings]="changed"
[class.docker-warning]="dockerWarning"
[hidden]="shouldHide">
@ -546,7 +547,7 @@
</div>
</div>
<small class="form-text text-muted">
<small class="form-text text-muted" *ngIf="settingsService.configStyle == ConfigStyle.full">
<ng-container *ngIf="experimental">
<span class="oi oi-warning"></span>[Experimental]
</ng-container>

View File

@ -12,7 +12,7 @@ import {
TAGS,
ThemeConfig
} from '../../../../../../common/config/public/ClientConfig';
import {SettingsService} from '../../settings.service';
import {ConfigStyle, SettingsService} from '../../settings.service';
import {WebConfig} from '../../../../../../common/config/private/WebConfig';
import {JobScheduleConfig, UserConfig} from '../../../../../../common/config/private/PrivateConfig';
import {enumToTranslatedArray} from '../../../EnumTranslations';
@ -79,6 +79,7 @@ export class SettingsEntryComponent
newThemeModalRef: any;
iconModal: { ref?: any, error?: string };
@Input() noChangeDetection = false;
public readonly ConfigStyle = ConfigStyle;
constructor(private searchQueryParserService: SearchQueryParserService,

View File

@ -69,7 +69,7 @@
<ng-template #Recursion let-rStates="rStates" let-topLevel="topLevel" let-skipJobs="skipJobs"
let-confPath="confPath">
<div class="alert alert-secondary" role="alert" *ngIf="rStates.description">
<div class="alert alert-secondary" role="alert" *ngIf="rStates.description && settingsService.configStyle == ConfigStyle.full">
{{rStates.description}}
<a *ngIf="rStates.tags?.githubIssue"
[href]="'https://github.com/bpatrik/pigallery2/issues/'+rStates.tags?.githubIssue">
@ -124,7 +124,7 @@
<ng-template #JobTemplate let-uiJob="uiJob">
<div class="mb-2">
<ng-container *ngFor="let job of uiJob; let i = index">
<div class="alert alert-secondary" role="alert" *ngIf="job.description">
<div class="alert alert-secondary" role="alert" *ngIf="job.description && settingsService.configStyle == ConfigStyle.full">
{{job.description}}
</div>
<app-settings-job-button

View File

@ -2,7 +2,7 @@ import {Component, Input, OnChanges, OnDestroy, OnInit, ViewChild} from '@angula
import {AuthenticationService} from '../../../model/network/authentication.service';
import {NavigationService} from '../../../model/navigation.service';
import {NotificationService} from '../../../model/notification.service';
import {SettingsService} from '../settings.service';
import {ConfigStyle, SettingsService} from '../settings.service';
import {WebConfig} from '../../../../../common/config/private/WebConfig';
import {JobProgressDTO} from '../../../../../common/entities/job/JobProgressDTO';
import {JobDTOUtils} from '../../../../../common/entities/job/JobDTO';
@ -76,6 +76,8 @@ export class TemplateComponent implements OnInit, OnChanges, OnDestroy, ISetting
private settingsSubscription: Subscription = null;
protected sliceFN?: (s: IWebConfigClassPrivate<TAGS> & WebConfig) => ConfigState;
public readonly ConfigStyle = ConfigStyle;
constructor(
protected authService: AuthenticationService,
private navigation: NavigationService,

View File

@ -63,13 +63,15 @@
[ngValue]="jobTrigger.key">{{jobTrigger.value}}
</option>
</select>
<small class="form-text text-muted"
<small class="form-text text-muted" *ngIf="settingsService.configStyle == ConfigStyle.full"
i18n>Set the time to run the job.
</small>
</div>
</div>
<div class="mb-3 row" *ngIf="schedule.trigger.type == JobTriggerType.after">
<div class="mb-1 row"
[class.mb-3]="settingsService.configStyle == ConfigStyle.full"
*ngIf="schedule.trigger.type == JobTriggerType.after">
<label class="col-md-2 control-label" [for]="'triggerAfter'+i" i18n>After:</label>
<div class="col-md-10">
<select class="form-select"
@ -82,14 +84,16 @@
</option>
</ng-container>
</select>
<small class="form-text text-muted"
<small class="form-text text-muted" *ngIf="settingsService.configStyle == ConfigStyle.full"
i18n>The job will run after that job finishes.
</small>
</div>
</div>
<div class="mb-3 row" *ngIf="schedule.trigger.type == JobTriggerType.scheduled">
<div class="mb-1 row"
[class.mb-3]="settingsService.configStyle == ConfigStyle.full"
*ngIf="schedule.trigger.type == JobTriggerType.scheduled">
<label class="col-md-2 control-label" [for]="'triggerTime'+i" i18n>At:</label>
<div class="col-md-10">
<app-timestamp-datepicker
@ -99,7 +103,9 @@
</div>
</div>
<div class="mb-3 row" *ngIf="schedule.trigger.type == JobTriggerType.periodic">
<div class="mb-1 row"
[class.mb-3]="settingsService.configStyle == ConfigStyle.full"
*ngIf="schedule.trigger.type == JobTriggerType.periodic">
<label class="col-md-2 control-label" [for]="'periodicity'+i" i18n>At:</label>
<div class="col-md-10">
<select
@ -121,7 +127,8 @@
</div>
</div>
<div class="mb-3 row">
<div class="mb-1 row"
[class.mb-3]="settingsService.configStyle == ConfigStyle.full">
<label class="col-md-2 control-label" [for]="'allowParallelRun'+'_'+i" i18n>Allow parallel run</label>
<div class="col-md-10">
<div class="input-group">
@ -137,7 +144,7 @@
[(ngModel)]="schedule.allowParallelRun">
</div>
</div>
<small class="form-text text-muted"
<small class="form-text text-muted" *ngIf="settingsService.configStyle == ConfigStyle.full"
i18n>Enables the job to start even if another job is already running.
</small>
</div>
@ -151,7 +158,8 @@
<hr/>
<div *ngFor="let configEntry of jobsService.getConfigTemplate(schedule.jobName)">
<div class="mb-3 row">
<div class="mb-1 row"
[class.mb-3]="settingsService.configStyle == ConfigStyle.full">
<label class="col-md-2 control-label"
[for]="configEntry.id+'_'+i">{{backendTextService.get(configEntry.name)}}</label>
<div class="col-md-10">
@ -211,7 +219,8 @@
<ng-container *ngSwitchCase="'MediaPickDTO-array'">
<ng-container *ngFor="let mp of AsMediaPickDTOArray(schedule.config[configEntry.id]); let j=index">
<div class="mb-3 row">
<div class="mb-1 row"
[class.mb-3]="settingsService.configStyle == ConfigStyle.full">
<label class="col-md-2 control-label"
[for]="configEntry.id+'_'+i" i18n>Search Query - {{(j + 1)}}</label>
<div class="col-md-10">
@ -224,12 +233,13 @@
placeholder="Search Query">
</app-gallery-search-field>
</div>
<small class="form-text text-muted" i18n>
<small class="form-text text-muted" *ngIf="settingsService.configStyle == ConfigStyle.full" i18n>
Search query to list photos and videos.
</small>
</div>
</div>
<div class="mb-3 row">
<div class="mb-1 row"
[class.mb-3]="settingsService.configStyle == ConfigStyle.full">
<label class="col-md-2 control-label"
[for]="configEntry.id+'_'+i" i18n>Sort by</label>
<div class="col-md-10">
@ -270,12 +280,13 @@
</button>
</div>
</div>
<small class="form-text text-muted" i18n>
<small class="form-text text-muted" *ngIf="settingsService.configStyle == ConfigStyle.full" i18n>
Sorts the photos and videos by this.
</small>
</div>
</div>
<div class="mb-3 row">
<div class="mb-1 row"
[class.mb-3]="settingsService.configStyle == ConfigStyle.full">
<label class="col-md-2 control-label"
[for]="configEntry.id+'_'+i" i18n>Pick</label>
<div class="col-md-10">
@ -285,7 +296,7 @@
(ngModelChange)="onChange($event)"
[(ngModel)]="mp.pick" required>
</div>
<small class="form-text text-muted" i18n>
<small class="form-text text-muted" *ngIf="settingsService.configStyle == ConfigStyle.full" i18n>
Number of photos and videos to pick.
</small>
</div>
@ -319,7 +330,7 @@
</ng-container>
</div>
<small class="form-text text-muted">
<small class="form-text text-muted" *ngIf="settingsService.configStyle == ConfigStyle.full">
<ng-container *ngIf="configEntry.type == 'number-array'" i18n>';' separated integers.
</ng-container>
{{backendTextService.get(configEntry.description)}}
@ -365,7 +376,7 @@
[ngValue]="availableJob.Name">{{backendTextService.getJobName(availableJob.Name)}}
</option>
</select>
<small class="form-text text-muted"
<small class="form-text text-muted" *ngIf="settingsService.configStyle == ConfigStyle.full"
i18n>Select a job to schedule.
</small>

View File

@ -9,7 +9,7 @@ import {
} from '../../../../../common/entities/job/JobScheduleDTO';
import {ScheduledJobsService} from '../scheduled-jobs.service';
import {BackendtextService} from '../../../model/backendtext.service';
import {SettingsService} from '../settings.service';
import {ConfigStyle, SettingsService} from '../settings.service';
import {JobProgressDTO, JobProgressStates} from '../../../../../common/entities/job/JobProgressDTO';
import {
AfterJobTriggerConfig,
@ -64,7 +64,7 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
},
allowParallelRun: false,
};
public readonly ConfigStyle = ConfigStyle;
SortingMethods = enumToTranslatedArray(SortingMethods);
@ -317,4 +317,5 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
pick: 5
});
}
}