mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-01-26 05:27:35 +02:00
Improving config UI #569
This commit is contained in:
parent
36d4641e9d
commit
875d120df8
@ -1,14 +1,10 @@
|
||||
import {
|
||||
ConfigTemplateEntry,
|
||||
DefaultsJobs,
|
||||
} from '../../../../common/entities/job/JobDTO';
|
||||
import {ConfigTemplateEntry, DefaultsJobs,} from '../../../../common/entities/job/JobDTO';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import {Job} from './Job';
|
||||
import {ProjectPath} from '../../../ProjectPath';
|
||||
import {PhotoProcessing} from '../../fileprocessing/PhotoProcessing';
|
||||
import {VideoProcessing} from '../../fileprocessing/VideoProcessing';
|
||||
import {DiskMangerWorker} from '../../threading/DiskMangerWorker';
|
||||
import {GPXProcessing} from '../../fileprocessing/GPXProcessing';
|
||||
|
||||
export class TempFolderCleaningJob extends Job {
|
||||
|
@ -331,8 +331,9 @@ export class ServerGPXCompressingConfig extends ClientGPXCompressingConfig {
|
||||
{
|
||||
name: $localize`Min distance`,
|
||||
priority: ConfigPriority.underTheHood,
|
||||
unit: 'm',
|
||||
uiDisabled: (sc: ServerGPXCompressingConfig, c: ServerConfig) => !c.Map.enabled || !sc.enabled || !c.MetaFile.gpx
|
||||
},
|
||||
} as TAGS,
|
||||
description: $localize`Filters out entry that are closer than this in meters.`
|
||||
})
|
||||
minDistance: number = 5;
|
||||
@ -356,8 +357,12 @@ export class ServerMetaFileConfig extends ClientMetaFileConfig {
|
||||
tags:
|
||||
{
|
||||
name: $localize`GPX compression`,
|
||||
priority: ConfigPriority.advanced
|
||||
}
|
||||
priority: ConfigPriority.advanced,
|
||||
uiJob: [{
|
||||
job: DefaultsJobs[DefaultsJobs['GPX Compression']],
|
||||
relevant: (c) => c.MetaFile.GPXCompressing.enabled
|
||||
}]
|
||||
} as TAGS
|
||||
})
|
||||
GPXCompressing: ServerGPXCompressingConfig = new ServerGPXCompressingConfig();
|
||||
}
|
||||
@ -419,8 +424,8 @@ export class ServerIndexingConfig {
|
||||
{
|
||||
name: $localize`Exclude File List`,
|
||||
priority: ConfigPriority.advanced,
|
||||
uiOptional: true
|
||||
|
||||
uiOptional: true,
|
||||
hint: $localize`.ignore;.pg2ignore`
|
||||
} as TAGS,
|
||||
description: $localize`Files that mark a folder to be excluded from indexing. Any folder that contains a file with this name will be excluded from indexing.`,
|
||||
})
|
||||
@ -610,7 +615,7 @@ export class ServerJobConfig {
|
||||
DefaultsJobs[DefaultsJobs.Indexing],
|
||||
DefaultsJobs[DefaultsJobs.Indexing],
|
||||
new NeverJobTriggerConfig(),
|
||||
{indexChangesOnly: true} // set config explicitly so it not undefined on the UI
|
||||
{indexChangesOnly: true} // set config explicitly so it is not undefined on the UI
|
||||
),
|
||||
new JobScheduleConfig(
|
||||
DefaultsJobs[DefaultsJobs['Preview Filling']],
|
||||
@ -681,7 +686,7 @@ export class VideoTranscodingConfig {
|
||||
tags:
|
||||
{
|
||||
name: $localize`FPS`,
|
||||
priority: ConfigPriority.advanced,
|
||||
priority: ConfigPriority.underTheHood,
|
||||
uiOptions: [24, 25, 30, 48, 50, 60]
|
||||
},
|
||||
description: $localize`Target frame per second (fps) of the output video will be scaled down this this.`
|
||||
@ -700,7 +705,7 @@ export class VideoTranscodingConfig {
|
||||
tags:
|
||||
{
|
||||
name: $localize`MP4 codec`,
|
||||
priority: ConfigPriority.advanced,
|
||||
priority: ConfigPriority.underTheHood,
|
||||
uiOptions: ['libx264', 'libx265'],
|
||||
relevant: (c: any) => c.format === 'mp4'
|
||||
}
|
||||
@ -710,7 +715,7 @@ export class VideoTranscodingConfig {
|
||||
tags:
|
||||
{
|
||||
name: $localize`Webm Codec`,
|
||||
priority: ConfigPriority.advanced,
|
||||
priority: ConfigPriority.underTheHood,
|
||||
uiOptions: ['libvpx', 'libvpx-vp9'],
|
||||
relevant: (c: any) => c.format === 'webm'
|
||||
}
|
||||
@ -782,6 +787,8 @@ export class PhotoConvertingConfig extends ClientPhotoConvertingConfig {
|
||||
tags: {
|
||||
name: $localize`Resolution`,
|
||||
priority: ConfigPriority.advanced,
|
||||
uiOptions: [720, 1080, 1440, 2160, 4320],
|
||||
unit: 'px',
|
||||
uiDisabled: (sc: PhotoConvertingConfig) =>
|
||||
!sc.enabled
|
||||
},
|
||||
@ -867,23 +874,34 @@ export class ServerMediaConfig extends ClientMediaConfig {
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Video`,
|
||||
priority: ConfigPriority.advanced
|
||||
},
|
||||
priority: ConfigPriority.advanced,
|
||||
uiJob: [
|
||||
{
|
||||
job: DefaultsJobs[DefaultsJobs['Video Converting']],
|
||||
relevant: (c) => c.Media.Video.enabled
|
||||
}]
|
||||
} as TAGS,
|
||||
description: $localize`Video support uses ffmpeg. ffmpeg and ffprobe binaries need to be available in the PATH or the @ffmpeg-installer/ffmpeg and @ffprobe-installer/ffprobe optional node packages need to be installed.`
|
||||
})
|
||||
Video: ServerVideoConfig = new ServerVideoConfig();
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Photo`,
|
||||
priority: ConfigPriority.advanced
|
||||
}
|
||||
priority: ConfigPriority.advanced,
|
||||
uiJob: [
|
||||
{
|
||||
job: DefaultsJobs[DefaultsJobs['Photo Converting']],
|
||||
relevant: (c) => c.Media.Photo.Converting.enabled
|
||||
}]
|
||||
} as TAGS
|
||||
})
|
||||
Photo: ServerPhotoConfig = new ServerPhotoConfig();
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Thumbnail`,
|
||||
priority: ConfigPriority.advanced
|
||||
}
|
||||
priority: ConfigPriority.advanced,
|
||||
uiJob: [{job: DefaultsJobs[DefaultsJobs['Thumbnail Generation']]}]
|
||||
} as TAGS
|
||||
})
|
||||
Thumbnail: ServerThumbnailConfig = new ServerThumbnailConfig();
|
||||
}
|
||||
@ -965,34 +983,99 @@ export class ServerConfig extends ClientConfig {
|
||||
@ConfigProperty({volatile: true})
|
||||
Environment: ServerEnvironmentConfig = new ServerEnvironmentConfig();
|
||||
|
||||
@ConfigProperty()
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Server`,
|
||||
uiIcon: 'cog'
|
||||
} as TAGS,
|
||||
})
|
||||
Server: ServerServiceConfig = new ServerServiceConfig();
|
||||
|
||||
@ConfigProperty()
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Database`,
|
||||
uiIcon: 'list'
|
||||
} as TAGS
|
||||
})
|
||||
Database: ServerDataBaseConfig = new ServerDataBaseConfig();
|
||||
|
||||
@ConfigProperty()
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Users`,
|
||||
uiIcon: 'person'
|
||||
} as TAGS,
|
||||
})
|
||||
Users: ServerUserConfig = new ServerUserConfig();
|
||||
|
||||
@ConfigProperty()
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Indexing`,
|
||||
uiIcon: 'pie-chart',
|
||||
uiJob: [
|
||||
{
|
||||
job: DefaultsJobs[DefaultsJobs.Indexing],
|
||||
description: $localize`If you add a new folder to your gallery, the site indexes it automatically. If you would like to trigger indexing manually, click index button. (Note: search only works among the indexed directories.)`
|
||||
}, {
|
||||
job: DefaultsJobs[DefaultsJobs['Database Reset']],
|
||||
hideProgress: true
|
||||
}]
|
||||
} as TAGS
|
||||
})
|
||||
Indexing: ServerIndexingConfig = new ServerIndexingConfig();
|
||||
|
||||
@ConfigProperty()
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Media`,
|
||||
uiIcon: 'camera-slr'
|
||||
} as TAGS,
|
||||
})
|
||||
Media: ServerMediaConfig = new ServerMediaConfig();
|
||||
|
||||
@ConfigProperty()
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Meta file`,
|
||||
uiIcon: 'file'
|
||||
} as TAGS,
|
||||
})
|
||||
MetaFile: ServerMetaFileConfig = new ServerMetaFileConfig();
|
||||
|
||||
@ConfigProperty()
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Preview`,
|
||||
uiIcon: 'image',
|
||||
uiJob: [
|
||||
{
|
||||
job: DefaultsJobs[DefaultsJobs['Preview Filling']],
|
||||
}, {
|
||||
job: DefaultsJobs[DefaultsJobs['Preview Reset']],
|
||||
hideProgress: true
|
||||
}]
|
||||
} as TAGS
|
||||
})
|
||||
Preview: ServerPreviewConfig = new ServerPreviewConfig();
|
||||
|
||||
@ConfigProperty()
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Sharing`,
|
||||
uiIcon: 'share'
|
||||
} as TAGS,
|
||||
})
|
||||
Sharing: ServerSharingConfig = new ServerSharingConfig();
|
||||
|
||||
@ConfigProperty()
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Duplicates`,
|
||||
uiIcon: 'layers'
|
||||
} as TAGS
|
||||
})
|
||||
Duplicates: ServerDuplicatesConfig = new ServerDuplicatesConfig();
|
||||
|
||||
@ConfigProperty()
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Jobs`,
|
||||
uiIcon: 'project'
|
||||
} as TAGS
|
||||
})
|
||||
Jobs: ServerJobConfig = new ServerJobConfig();
|
||||
}
|
||||
|
||||
|
@ -33,11 +33,18 @@ export type TAGS = {
|
||||
secret?: boolean, // these config properties should never travel out of the server
|
||||
experimental?: boolean, //is it a beta feature
|
||||
unit?: string, // Unit info to display on UI
|
||||
uiIcon?: string,
|
||||
uiType?: 'SearchQuery', // Hint for the UI about the type
|
||||
uiOptions?: (string | number)[], //Hint for the UI about the recommended options
|
||||
uiAllowSpaces?: boolean
|
||||
uiOptional?: boolean; //makes the tag not "required"
|
||||
uiDisabled?: (subConfig: any, config: ClientConfig) => boolean
|
||||
uiJob?: {
|
||||
job: string,
|
||||
hideProgress: boolean,
|
||||
relevant?: (c: ClientConfig) => boolean,
|
||||
description: string
|
||||
}[]
|
||||
};
|
||||
|
||||
@SubConfigClass<TAGS>({tags: {client: true}})
|
||||
@ -278,7 +285,7 @@ export class ClientMapConfig {
|
||||
tags: {
|
||||
name: $localize`Max Preview Markers`,
|
||||
priority: ConfigPriority.underTheHood
|
||||
},
|
||||
} as TAGS,
|
||||
description: $localize`Maximum number of markers to be shown on the map preview on the gallery page.`,
|
||||
})
|
||||
maxPreviewMarkers: number = 50;
|
||||
@ -289,7 +296,8 @@ export class ClientThumbnailConfig {
|
||||
@ConfigProperty({
|
||||
type: 'unsignedInt', max: 100,
|
||||
tags: {
|
||||
name: $localize`Max Preview Markers`,
|
||||
name: $localize`Map Icon size`,
|
||||
unit: 'px',
|
||||
priority: ConfigPriority.underTheHood
|
||||
},
|
||||
description: $localize`Icon size (used on maps).`,
|
||||
@ -298,6 +306,7 @@ export class ClientThumbnailConfig {
|
||||
@ConfigProperty({
|
||||
type: 'unsignedInt', tags: {
|
||||
name: $localize`Person thumbnail size`,
|
||||
unit: 'px',
|
||||
priority: ConfigPriority.underTheHood
|
||||
},
|
||||
description: $localize`Person (face) thumbnail size.`,
|
||||
@ -732,8 +741,9 @@ 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`,
|
||||
hint: typeof window !== 'undefined' ? window?.origin : '',
|
||||
uiOptional: true
|
||||
}
|
||||
} as TAGS
|
||||
})
|
||||
publicUrl: string = '';
|
||||
|
||||
@ -804,72 +814,57 @@ export class ClientUserConfig {
|
||||
@SubConfigClass<TAGS>({tags: {client: true}})
|
||||
export class ClientConfig {
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Server`
|
||||
} as TAGS,
|
||||
})
|
||||
@ConfigProperty()
|
||||
Server: ClientServiceConfig = new ClientServiceConfig();
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Users`
|
||||
} as TAGS,
|
||||
})
|
||||
@ConfigProperty()
|
||||
Users: ClientUserConfig = new ClientUserConfig();
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Gallery`
|
||||
name: $localize`Gallery`,
|
||||
uiIcon: 'browser'
|
||||
} as TAGS,
|
||||
})
|
||||
Gallery: ClientGalleryConfig = new ClientGalleryConfig();
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Media`
|
||||
} as TAGS,
|
||||
})
|
||||
@ConfigProperty()
|
||||
Media: ClientMediaConfig = new ClientMediaConfig();
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Meta file`
|
||||
} as TAGS,
|
||||
})
|
||||
@ConfigProperty()
|
||||
MetaFile: ClientMetaFileConfig = new ClientMetaFileConfig();
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Album`
|
||||
name: $localize`Album`,
|
||||
uiIcon: 'grid-two-up'
|
||||
} as TAGS,
|
||||
})
|
||||
Album: ClientAlbumConfig = new ClientAlbumConfig();
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Search`
|
||||
name: $localize`Search`,
|
||||
uiIcon: 'magnifying-glass'
|
||||
} as TAGS,
|
||||
})
|
||||
Search: ClientSearchConfig = new ClientSearchConfig();
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Sharing`
|
||||
} as TAGS,
|
||||
})
|
||||
@ConfigProperty()
|
||||
Sharing: ClientSharingConfig = new ClientSharingConfig();
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Map`
|
||||
name: $localize`Map`,
|
||||
uiIcon: 'map-marker'
|
||||
} as TAGS,
|
||||
})
|
||||
Map: ClientMapConfig = new ClientMapConfig();
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Faces`
|
||||
name: $localize`Faces`,
|
||||
uiIcon: 'people'
|
||||
} as TAGS,
|
||||
})
|
||||
Faces: ClientFacesConfig = new ClientFacesConfig();
|
||||
@ -877,6 +872,7 @@ export class ClientConfig {
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Random photo`,
|
||||
uiIcon: 'random',
|
||||
githubIssue: 392
|
||||
} as TAGS,
|
||||
description: $localize`This feature enables you to generate 'random photo' urls. That URL returns a photo random selected from your gallery. You can use the url with 3rd party application like random changing desktop background. Note: With the current implementation, random link also requires login.`
|
||||
|
@ -86,68 +86,68 @@
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<app-settings-template
|
||||
*ngFor="let cp of configPaths"
|
||||
#setting
|
||||
#tmpl
|
||||
icon="list"
|
||||
[ConfigPath]="cp"
|
||||
[hidden]="!tmpl.HasAvailableSettings"></app-settings-template>
|
||||
<!-- <app-settings-template #setting #server
|
||||
icon="list"
|
||||
[ConfigPath]="'Server'"
|
||||
[hidden]="!server.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #users
|
||||
icon="person"
|
||||
[ConfigPath]="'Users'"
|
||||
[hidden]="!users.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #db
|
||||
icon="list"
|
||||
[ConfigPath]="'Database'"
|
||||
[hidden]="!db.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #media
|
||||
icon="camera-slr"
|
||||
[ConfigPath]="'Media'"
|
||||
[hidden]="!media.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #gallery
|
||||
icon="browser"
|
||||
[ConfigPath]="'Gallery'"
|
||||
[hidden]="!gallery.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #preview
|
||||
icon="image"
|
||||
[ConfigPath]="'Preview'"
|
||||
[hidden]="!preview.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #metafile
|
||||
icon="file"
|
||||
[ConfigPath]="'MetaFile'"
|
||||
[hidden]="!metafile.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #map
|
||||
icon="map-marker"
|
||||
[ConfigPath]="'Map'"
|
||||
[hidden]="!map.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #sharing
|
||||
icon="share"
|
||||
[ConfigPath]="'Sharing'"
|
||||
[hidden]="!sharing.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #faces
|
||||
icon="people"
|
||||
[ConfigPath]="'Faces'"
|
||||
[hidden]="!faces.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #album
|
||||
icon="grid-two-up"
|
||||
[ConfigPath]="'Album'"
|
||||
[hidden]="!album.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #randomPhoto
|
||||
icon="random"
|
||||
[ConfigPath]="'RandomPhoto'"
|
||||
[hidden]="!randomPhoto.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #duplicates
|
||||
icon="layers"
|
||||
[ConfigPath]="'Duplicates'"
|
||||
[hidden]="!duplicates.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #indexing
|
||||
icon="pie-chart"
|
||||
[ConfigPath]="'Indexing'"
|
||||
[hidden]="!indexing.HasAvailableSettings"></app-settings-template>-->
|
||||
*ngFor="let cp of configPaths"
|
||||
#setting
|
||||
#tmpl
|
||||
icon="list"
|
||||
[ConfigPath]="cp"
|
||||
[hidden]="!tmpl.HasAvailableSettings"></app-settings-template>
|
||||
<!-- <app-settings-template #setting #server
|
||||
icon="list"
|
||||
[ConfigPath]="'Server'"
|
||||
[hidden]="!server.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #users
|
||||
icon="person"
|
||||
[ConfigPath]="'Users'"
|
||||
[hidden]="!users.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #db
|
||||
icon="list"
|
||||
[ConfigPath]="'Database'"
|
||||
[hidden]="!db.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #media
|
||||
icon="camera-slr"
|
||||
[ConfigPath]="'Media'"
|
||||
[hidden]="!media.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #gallery
|
||||
icon="browser"
|
||||
[ConfigPath]="'Gallery'"
|
||||
[hidden]="!gallery.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #preview
|
||||
icon="image"
|
||||
[ConfigPath]="'Preview'"
|
||||
[hidden]="!preview.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #metafile
|
||||
icon="file"
|
||||
[ConfigPath]="'MetaFile'"
|
||||
[hidden]="!metafile.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #map
|
||||
icon="map-marker"
|
||||
[ConfigPath]="'Map'"
|
||||
[hidden]="!map.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #sharing
|
||||
icon="share"
|
||||
[ConfigPath]="'Sharing'"
|
||||
[hidden]="!sharing.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #faces
|
||||
icon="people"
|
||||
[ConfigPath]="'Faces'"
|
||||
[hidden]="!faces.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #album
|
||||
icon="grid-two-up"
|
||||
[ConfigPath]="'Album'"
|
||||
[hidden]="!album.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #randomPhoto
|
||||
icon="random"
|
||||
[ConfigPath]="'RandomPhoto'"
|
||||
[hidden]="!randomPhoto.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #duplicates
|
||||
icon="layers"
|
||||
[ConfigPath]="'Duplicates'"
|
||||
[hidden]="!duplicates.HasAvailableSettings"></app-settings-template>
|
||||
<app-settings-template #setting #indexing
|
||||
icon="pie-chart"
|
||||
[ConfigPath]="'Indexing'"
|
||||
[hidden]="!indexing.HasAvailableSettings"></app-settings-template>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -49,8 +49,7 @@ export interface RecursiveState extends ConfigState {
|
||||
@Directive()
|
||||
export abstract class SettingsComponentDirective<
|
||||
T extends RecursiveState> implements OnInit, OnDestroy, ISettingsComponent {
|
||||
|
||||
@Input() icon: string;
|
||||
public icon: string;
|
||||
@Input() ConfigPath: string;
|
||||
|
||||
@ViewChild('settingsForm', {static: true})
|
||||
@ -72,7 +71,7 @@ export abstract class SettingsComponentDirective<
|
||||
private navigation: NavigationService,
|
||||
public settingsService: AbstractSettingsService,
|
||||
protected notification: NotificationService,
|
||||
protected globalSettingsService: SettingsService,
|
||||
public globalSettingsService: SettingsService,
|
||||
sliceFN?: (s: IWebConfigClassPrivate<TAGS> & WebConfig) => T
|
||||
) {
|
||||
this.setSliceFN(sliceFN);
|
||||
@ -108,6 +107,7 @@ export abstract class SettingsComponentDirective<
|
||||
if (state.volatile) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (state.tags &&
|
||||
((state.tags.relevant && !state.tags.relevant(parent.value))
|
||||
|| state.tags.secret)) {
|
||||
@ -135,12 +135,11 @@ export abstract class SettingsComponentDirective<
|
||||
return (
|
||||
(state.tags?.priority > this.globalSettingsService.configPriority ||
|
||||
(this.globalSettingsService.configPriority === ConfigPriority.basic &&
|
||||
state.tags?.dockerSensitive && this.globalSettingsService.settings.value.Environment.isDocker)) && //if this value should not change in Docker, lets hide it
|
||||
state.tags?.dockerSensitive && this.globalSettingsService.settings.value.Environment.isDocker)) && //if this value should not change in Docker, lets hide it
|
||||
Utils.equalsFilter(state.value, state.default,
|
||||
['__propPath', '__created', '__prototype', '__rootConfig']) &&
|
||||
Utils.equalsFilter(state.original, state.default,
|
||||
['__propPath', '__created', '__prototype', '__rootConfig'])
|
||||
);
|
||||
['__propPath', '__created', '__prototype', '__rootConfig']));
|
||||
};
|
||||
};
|
||||
|
||||
@ -164,6 +163,7 @@ export abstract class SettingsComponentDirective<
|
||||
}
|
||||
};
|
||||
instrument(this.states, null);
|
||||
this.icon = this.states.tags?.uiIcon;
|
||||
};
|
||||
|
||||
onOptionChange = () => {
|
||||
|
@ -13,8 +13,6 @@
|
||||
<div class="col-md-10">
|
||||
|
||||
<div class="input-group">
|
||||
|
||||
|
||||
<app-gallery-search-field
|
||||
*ngIf="Type === 'SearchQuery'"
|
||||
[(ngModel)]="state.value"
|
||||
@ -296,7 +294,9 @@
|
||||
</div>
|
||||
<small class="form-text text-muted" *ngIf="description">{{description}}
|
||||
<span *ngIf="Type==='array' && (state.arrayType === 'string' || isNumberArray)" i18n>';' separated list.</span>
|
||||
<a *ngIf="link" [href]="link">{{linkText || link}}</a>
|
||||
<a *ngIf="state.tags?.githubIssue"
|
||||
[href]="'https://github.com/bpatrik/pigallery2/issues/'+state.tags?.githubIssue">See
|
||||
#{{state.tags?.githubIssue}}.</a>
|
||||
</small>
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
|
@ -1,22 +1,9 @@
|
||||
import {Component, forwardRef, Input, OnChanges} from '@angular/core';
|
||||
import {
|
||||
ControlValueAccessor,
|
||||
FormControl,
|
||||
NG_VALIDATORS,
|
||||
NG_VALUE_ACCESSOR,
|
||||
ValidationErrors,
|
||||
Validator,
|
||||
} from '@angular/forms';
|
||||
import {ControlValueAccessor, NG_VALIDATORS, NG_VALUE_ACCESSOR, ValidationErrors, Validator,} from '@angular/forms';
|
||||
import {Utils} from '../../../../../../common/Utils';
|
||||
import {IConfigClass, propertyTypes} from 'typeconfig/common';
|
||||
import {propertyTypes} from 'typeconfig/common';
|
||||
import {SearchQueryParserService} from '../../../gallery/search/search-query-parser.service';
|
||||
import {
|
||||
ClientThumbnailConfig,
|
||||
ConfigPriority,
|
||||
MapLayers,
|
||||
NavigationLinkConfig, NavigationLinkTypes,
|
||||
TAGS
|
||||
} from '../../../../../../common/config/public/ClientConfig';
|
||||
import {MapLayers, NavigationLinkConfig, NavigationLinkTypes, TAGS} from '../../../../../../common/config/public/ClientConfig';
|
||||
import {SettingsService} from '../../settings.service';
|
||||
import {WebConfig} from '../../../../../../common/config/private/WebConfig';
|
||||
import {JobScheduleConfig, UserConfig} from '../../../../../../common/config/private/PrivateConfig';
|
||||
@ -61,16 +48,12 @@ interface IState {
|
||||
})
|
||||
export class SettingsEntryComponent
|
||||
implements ControlValueAccessor, Validator, OnChanges {
|
||||
@Input() defaultName: string;
|
||||
name: string;
|
||||
@Input() required: boolean;
|
||||
@Input() dockerWarning: boolean;
|
||||
@Input() placeholder: string;
|
||||
@Input() allowSpaces = false;
|
||||
@Input() description: string;
|
||||
@Input() link: string;
|
||||
@Input() linkText: string;
|
||||
@Input() typeOverride: 'SearchQuery';
|
||||
required: boolean;
|
||||
dockerWarning: boolean;
|
||||
placeholder: string;
|
||||
allowSpaces = false;
|
||||
description: string;
|
||||
state: IState;
|
||||
isNumberArray = false;
|
||||
isNumber = false;
|
||||
@ -89,13 +72,14 @@ export class SettingsEntryComponent
|
||||
if (this.Disabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.state.isConfigArrayType) {
|
||||
for (let i = 0; i < this.state.value?.length; ++i) {
|
||||
for (const k of Object.keys(this.state.value[i].__state)) {
|
||||
if (!Utils.equalsFilter(
|
||||
this.state.value[i]?.__state[k]?.value,
|
||||
this.state.default[i]?.__state[k]?.value,
|
||||
['__propPath', '__created', '__prototype', '__rootConfig'])) {
|
||||
['default', '__propPath', '__created', '__prototype', '__rootConfig'])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -128,7 +112,7 @@ export class SettingsEntryComponent
|
||||
}
|
||||
|
||||
get Type(): string | object {
|
||||
return this.typeOverride || this.state.tags?.uiType || this.state.type;
|
||||
return this.state.tags?.uiType || this.state.type;
|
||||
}
|
||||
|
||||
get ArrayType(): string {
|
||||
@ -216,7 +200,7 @@ export class SettingsEntryComponent
|
||||
this.title = $localize`readonly` + ', ';
|
||||
}
|
||||
this.title += $localize`default value` + ': ' + this.defaultStr;
|
||||
this.name = this.state?.tags?.name || this.defaultName;
|
||||
this.name = this.state?.tags?.name;
|
||||
if (this.name) {
|
||||
this.idName =
|
||||
this.GUID + this.name.toLowerCase().replace(new RegExp(' ', 'gm'), '-');
|
||||
@ -245,10 +229,6 @@ export class SettingsEntryComponent
|
||||
if (typeof this.dockerWarning === 'undefined') {
|
||||
this.dockerWarning = this.state.tags.dockerSensitive && this.settingsService.settings.value.Environment.isDocker;
|
||||
}
|
||||
if (this.state.tags.githubIssue) {
|
||||
this.link = `https://github.com/bpatrik/pigallery2/issues/` + this.state.tags.githubIssue;
|
||||
this.linkText = $localize`See` + ' ' + this.state.tags.githubIssue;
|
||||
}
|
||||
this.name = this.name || this.state.tags.name;
|
||||
this.allowSpaces = this.allowSpaces || this.state.tags.uiAllowSpaces;
|
||||
this.required = this.required || !this.state.tags.uiOptional;
|
||||
|
@ -1,3 +0,0 @@
|
||||
:host {
|
||||
display: inline-block;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
.panel-info {
|
||||
text-align: center;
|
||||
}
|
@ -24,9 +24,7 @@
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
<ng-container *ngIf="states.value.enabled !== false">
|
||||
|
||||
<div class="alert alert-secondary" role="alert" *ngIf="states.description">
|
||||
{{states.description}}
|
||||
</div>
|
||||
|
||||
<ng-container
|
||||
*ngTemplateOutlet="Recursion; context:{ rStates: states,skipEnabled:true,confPath:ConfigPath }"
|
||||
></ng-container>
|
||||
@ -48,16 +46,18 @@
|
||||
</div>
|
||||
|
||||
<ng-template #Recursion let-rStates="rStates" let-skipEnabled="skipEnabled" let-confPath="confPath">
|
||||
<div class="alert alert-secondary" role="alert" *ngIf="rStates.description">
|
||||
{{rStates.description}}
|
||||
</div>
|
||||
<ng-container *ngFor="let ck of getKeys(rStates)">
|
||||
<ng-container *ngIf="!(rStates.value.__state[ck].shouldHide && rStates.value.__state[ck].shouldHide())">
|
||||
<app-settings-entry
|
||||
*ngIf="(ck!=='enabled' || !skipEnabled) && !rStates.value.__state[ck].isConfigType"
|
||||
[name]="confPath+'_'+ck"
|
||||
[defaultName]="ck"
|
||||
[ngModel]="rStates?.value.__state[ck]">
|
||||
</app-settings-entry>
|
||||
<ng-container *ngIf="rStates.value.__state[ck].isConfigType">
|
||||
<div class="row">
|
||||
<div class="row mt-2">
|
||||
<div class="col-auto">
|
||||
<h5>{{rStates?.value.__state[ck].tags?.name || ck}}</h5>
|
||||
</div>
|
||||
@ -66,9 +66,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<div class="alert alert-secondary" role="alert" *ngIf="rStates.value.__state[ck]?.description">
|
||||
{{rStates.value.__state[ck]?.description}}
|
||||
</div>
|
||||
<ng-container
|
||||
*ngTemplateOutlet="Recursion; context:{ rStates: rStates.value.__state[ck], confPath:confPath+'.'+ck }"
|
||||
></ng-container>
|
||||
@ -76,6 +73,31 @@
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<div *ngIf="rStates.tags?.uiJob">
|
||||
<ng-container *ngFor="let job of rStates.tags?.uiJob; let i = index">
|
||||
<div class="alert alert-secondary" role="alert" *ngIf="job.description">
|
||||
{{job.description}}
|
||||
</div>
|
||||
<app-settings-job-button
|
||||
*ngIf="!job.relevant || job.relevant(globalSettingsService.settings | async)"
|
||||
class="mt-2 mb-1 mb-md-0 mt-md-0 float-left me-2"
|
||||
[soloRun]="true"
|
||||
(jobError)="error=$event"
|
||||
[allowParallelRun]="false"
|
||||
[danger]="i>0"
|
||||
[jobName]="job.job"></app-settings-job-button>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngFor="let job of rStates.tags?.uiJob">
|
||||
<ng-container
|
||||
*ngIf="getProgress(job.job) && !job.hideProgress && (!job.relevant || job.relevant(globalSettingsService.settings | async))">
|
||||
<hr class="mt-1"/>
|
||||
<app-settings-job-progress
|
||||
class="d-block mb-2"
|
||||
[progress]="getProgress(job.job)"></app-settings-job-progress>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-template>
|
||||
</form>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
@ -6,6 +6,9 @@ import {SettingsComponentDirective} from '../_abstract/abstract.settings.compone
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {WebConfig} from '../../../../../common/config/private/WebConfig';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {JobProgressDTO} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
import {JobDTOUtils} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -22,7 +25,8 @@ export class TemplateComponent extends SettingsComponentDirective<any> implement
|
||||
navigation: NavigationService,
|
||||
notification: NotificationService,
|
||||
settingsService: AbstractSettingsService,
|
||||
globalSettingsService: SettingsService
|
||||
globalSettingsService: SettingsService,
|
||||
public jobsService: ScheduledJobsService,
|
||||
) {
|
||||
super(
|
||||
authService,
|
||||
@ -66,4 +70,7 @@ export class TemplateComponent extends SettingsComponentDirective<any> implement
|
||||
});
|
||||
}
|
||||
|
||||
getProgress(jobName: string): JobProgressDTO {
|
||||
return this.jobsService.progress.value[JobDTOUtils.getHashName(jobName)];
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
.form-control {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.panel-info {
|
||||
text-align: center;
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
.buttons-row {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
@ -6,7 +6,6 @@ import {
|
||||
JobScheduleDTO,
|
||||
JobScheduleDTOUtils,
|
||||
JobTriggerType,
|
||||
PeriodicJobTrigger,
|
||||
ScheduledJobTrigger
|
||||
} from '../../../../../common/entities/job/JobScheduleDTO';
|
||||
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
@ -96,6 +95,9 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
|
||||
}
|
||||
|
||||
atTimeLocal(atTime: number): Date {
|
||||
if (!atTime) {
|
||||
return null;
|
||||
}
|
||||
const d = new Date();
|
||||
d.setUTCHours(Math.floor(atTime / 60));
|
||||
d.setUTCMinutes(Math.floor(atTime % 60));
|
||||
@ -156,6 +158,8 @@ export class WorkflowComponent implements ControlValueAccessor, Validator, OnIni
|
||||
|
||||
case JobTriggerType.periodic:
|
||||
schedule.trigger = new PeriodicJobTriggerConfig();
|
||||
schedule.trigger.periodicity = 7;
|
||||
schedule.trigger.atTime = 0;
|
||||
break;
|
||||
|
||||
case JobTriggerType.after:
|
||||
|
Loading…
x
Reference in New Issue
Block a user