mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-11-28 08:58:49 +02:00
updating settings page
This commit is contained in:
parent
3633168ee4
commit
2012ec3d91
@ -74,6 +74,7 @@
|
||||
"tsConfig": "frontend/tsconfig.spec.json",
|
||||
"scripts": [],
|
||||
"styles": [
|
||||
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||
"node_modules/ngx-toastr/toastr.css",
|
||||
"node_modules/bootstrap/dist/css/bootstrap.css",
|
||||
"node_modules/open-iconic/font/css/open-iconic-bootstrap.css",
|
||||
@ -131,4 +132,4 @@
|
||||
"prefix": "app"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||
import {ObjectManagers} from '../model/ObjectManagers';
|
||||
import {Logger} from '../Logger';
|
||||
import {SQLConnection} from '../model/sql/SQLConnection';
|
||||
import {DataBaseConfig, DatabaseType, IndexingConfig, ThumbnailConfig} from '../../common/config/private/IPrivateConfig';
|
||||
import {DataBaseConfig, DatabaseType, IndexingConfig, TaskConfig, ThumbnailConfig} from '../../common/config/private/IPrivateConfig';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
import {ConfigDiagnostics} from '../model/diagnostics/ConfigDiagnostics';
|
||||
import {ClientConfig} from '../../common/config/public/ConfigClass';
|
||||
@ -440,6 +440,35 @@ export class AdminMWs {
|
||||
}
|
||||
|
||||
|
||||
public static async updateTasksSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const settings: TaskConfig = req.body.settings;
|
||||
const original = Config.original();
|
||||
await ConfigDiagnostics.testTasksConfig(settings, original);
|
||||
|
||||
Config.Server.tasks = settings;
|
||||
original.Server.tasks = settings;
|
||||
original.save();
|
||||
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + err.toString(), err));
|
||||
}
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static startTask(req: Request, res: Response, next: NextFunction) {
|
||||
try {
|
||||
const id = req.params.id;
|
||||
|
@ -3,6 +3,7 @@ import {
|
||||
DataBaseConfig,
|
||||
DatabaseType,
|
||||
IPrivateConfig,
|
||||
TaskConfig,
|
||||
ThumbnailConfig,
|
||||
ThumbnailProcessingLib
|
||||
} from '../../../common/config/private/IPrivateConfig';
|
||||
@ -127,6 +128,10 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
|
||||
|
||||
static async testTasksConfig(faces: TaskConfig, config: IPrivateConfig) {
|
||||
|
||||
}
|
||||
|
||||
static async testFacesConfig(faces: ClientConfig.FacesConfig, config: IPrivateConfig) {
|
||||
if (faces.enabled === true) {
|
||||
if (config.Server.database.type === DatabaseType.memory) {
|
||||
@ -281,6 +286,17 @@ export class ConfigDiagnostics {
|
||||
Config.Client.Faces.enabled = false;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testTasksConfig(Config.Server.tasks, Config);
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning('Some Tasks are not supported with these settings. Disabling temporally. ' +
|
||||
'Please adjust the config properly.', err.toString());
|
||||
Logger.warn(LOG_TAG, 'Some Tasks not supported with these settings, switching off..', err.toString());
|
||||
Config.Client.Faces.enabled = false;
|
||||
}
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testSharingConfig(Config.Client.Sharing, Config);
|
||||
} catch (ex) {
|
||||
|
@ -3,6 +3,7 @@ import {TaskProgressDTO} from '../../../common/entities/settings/TaskProgressDTO
|
||||
import {ITask} from './ITask';
|
||||
import {TaskRepository} from './TaskRepository';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {TaskTriggerType} from '../../../common/entities/task/TaskScheduleDTO';
|
||||
|
||||
export class TaskManager implements ITaskManager {
|
||||
|
||||
@ -31,6 +32,34 @@ export class TaskManager implements ITaskManager {
|
||||
return TaskRepository.Instance.getAvailableTasks();
|
||||
}
|
||||
|
||||
public runSchedules(): void {
|
||||
Config.Server.tasks.scheduled.forEach(schedule => {
|
||||
let nextRun = null;
|
||||
switch (schedule.trigger.type) {
|
||||
case TaskTriggerType.scheduled:
|
||||
nextRun = Date.now() - schedule.trigger.time;
|
||||
break;
|
||||
/*case TaskTriggerType.periodic:
|
||||
|
||||
//TODo finish it
|
||||
const getNextDayOfTheWeek = (dayOfWeek: number) => {
|
||||
const refDate = new Date();
|
||||
refDate.setHours(0, 0, 0, 0);
|
||||
refDate.setDate(refDate.getDate() + (dayOfWeek + 7 - refDate.getDay()) % 7);
|
||||
return refDate;
|
||||
};
|
||||
|
||||
nextRun = Date.now() - schedule.trigger.periodicity;
|
||||
break;*/
|
||||
}
|
||||
|
||||
if (nextRun != null) {
|
||||
setTimeout(() => {
|
||||
this.start(schedule.taskName, schedule.config);
|
||||
}, nextRun);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected findTask(taskName: string): ITask<any> {
|
||||
return this.getAvailableTasks().find(t => t.Name === taskName);
|
||||
|
@ -174,6 +174,12 @@ export class AdminRouter {
|
||||
AdminMWs.updateIndexingSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
app.put('/api/settings/tasks',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.updateTasksSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,7 +12,7 @@ import * as path from 'path';
|
||||
import {ConfigLoader} from 'typeconfig';
|
||||
import {Utils} from '../../Utils';
|
||||
import {UserRoles} from '../../entities/UserDTO';
|
||||
import {TaskScheduleDTO, TaskTriggerType} from '../../entities/task/TaskScheduleDTO';
|
||||
import {TaskScheduleDTO} from '../../entities/task/TaskScheduleDTO';
|
||||
import {Config} from './Config';
|
||||
|
||||
/**
|
||||
@ -65,28 +65,7 @@ export class PrivateConfigClass extends PublicConfigClass implements IPrivateCon
|
||||
listingLimit: 1000
|
||||
},
|
||||
tasks: {
|
||||
scheduled: [
|
||||
{
|
||||
priority: 1,
|
||||
taskName: 'indexing',
|
||||
config: null,
|
||||
trigger: {
|
||||
type: TaskTriggerType.periodic,
|
||||
time: {
|
||||
offset: 0,
|
||||
repeat: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
priority: 2,
|
||||
taskName: 'Database reset',
|
||||
config: null,
|
||||
trigger: {
|
||||
type: TaskTriggerType.never
|
||||
}
|
||||
}
|
||||
]
|
||||
scheduled: []
|
||||
}
|
||||
};
|
||||
private ConfigLoader: any;
|
||||
|
@ -12,15 +12,13 @@ export interface NeverTaskTrigger {
|
||||
|
||||
export interface ScheduledTaskTrigger extends TaskTrigger {
|
||||
type: TaskTriggerType.scheduled;
|
||||
time: number;
|
||||
time: number; // data time
|
||||
}
|
||||
|
||||
export interface PeriodicTaskTrigger extends TaskTrigger {
|
||||
type: TaskTriggerType.periodic;
|
||||
time: {
|
||||
offset: number,
|
||||
repeat: number
|
||||
};
|
||||
periodicity: number; // 1-7: week days 8+ every x days
|
||||
atTime: number; // day time
|
||||
}
|
||||
|
||||
export interface TaskScheduleDTO {
|
||||
|
@ -83,6 +83,10 @@ import {ControlsLightboxComponent} from './ui/gallery/lightbox/controls/controls
|
||||
import {FacesSettingsComponent} from './ui/settings/faces/faces.settings.component';
|
||||
import {TasksSettingsComponent} from './ui/settings/tasks/tasks.settings.component';
|
||||
import {ScheduledTasksService} from './ui/settings/scheduled-tasks.service';
|
||||
import {TimepickerModule} from 'ngx-bootstrap/timepicker';
|
||||
import {TimeStampDatePickerComponent} from './ui/utils/timestamp-datepicker/datepicker.component';
|
||||
import {TimeStampTimePickerComponent} from './ui/utils/timestamp-timepicker/timepicker.component';
|
||||
|
||||
|
||||
|
||||
@Injectable()
|
||||
@ -141,7 +145,8 @@ export function translationsFactory(locale: string) {
|
||||
BsDropdownModule.forRoot(),
|
||||
SlimLoadingBarModule.forRoot(),
|
||||
BsDatepickerModule.forRoot(),
|
||||
YagaModule
|
||||
YagaModule,
|
||||
TimepickerModule.forRoot()
|
||||
],
|
||||
declarations: [AppComponent,
|
||||
LoginComponent,
|
||||
@ -151,6 +156,8 @@ export function translationsFactory(locale: string) {
|
||||
// misc
|
||||
FrameComponent,
|
||||
LanguageComponent,
|
||||
TimeStampDatePickerComponent,
|
||||
TimeStampTimePickerComponent,
|
||||
// Gallery
|
||||
GalleryLightboxMediaComponent,
|
||||
GalleryPhotoLoadingComponent,
|
||||
|
@ -14,7 +14,7 @@ import {Config} from '../../../../common/config/public/Config';
|
||||
})
|
||||
export class AdminComponent implements OnInit {
|
||||
|
||||
simplifiedMode = true;
|
||||
simplifiedMode = false;
|
||||
text = {
|
||||
Advanced: 'Advanced',
|
||||
Simplified: 'Simplified'
|
||||
|
@ -74,7 +74,8 @@ export abstract class SettingsComponent<T extends { [key: string]: any }, S exte
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
if (typeof original[key] === 'undefined') {
|
||||
throw new Error('unknown settings: ' + key);
|
||||
console.warn('unknown settings: ' + key);
|
||||
return false;
|
||||
}
|
||||
if (typeof original[key] === 'object') {
|
||||
if (this.settingsSame(newSettings[key], original[key]) === false) {
|
||||
@ -88,6 +89,13 @@ export abstract class SettingsComponent<T extends { [key: string]: any }, S exte
|
||||
return true;
|
||||
}
|
||||
|
||||
public testSettingChanges() {
|
||||
// TODO: fix after this issue is fixed: https://github.com/angular/angular/issues/24818
|
||||
setTimeout(() => {
|
||||
this.changed = !this.settingsSame(this.settings, this.original);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (!this._authService.isAuthenticated() ||
|
||||
this._authService.user.value.role < UserRoles.Admin) {
|
||||
@ -98,9 +106,7 @@ export abstract class SettingsComponent<T extends { [key: string]: any }, S exte
|
||||
|
||||
// TODO: fix after this issue is fixed: https://github.com/angular/angular/issues/24818
|
||||
this._subscription = this.form.valueChanges.subscribe(() => {
|
||||
setTimeout(() => {
|
||||
this.changed = !this.settingsSame(this.settings, this.original);
|
||||
}, 0);
|
||||
this.testSettingChanges();
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<form #settingsForm="ngForm" class="form-horizontal">
|
||||
<div class="card mb-4">
|
||||
<h5 class="card-header" i18n>
|
||||
Basic settings
|
||||
<ng-container i18n>Basic settings</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="card mb-4">
|
||||
<h5 class="card-header" i18n>
|
||||
Database settings
|
||||
<ng-container i18n>Database settings</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="card mb-4"
|
||||
[ngClass]="settings.enabled && !_settingsService.isSupported()?'panel-warning':''">
|
||||
<h5 class="card-header">
|
||||
<ng-container i18n>Faces settings</ng-container>
|
||||
<ng-container i18n>Faces settings</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
<div class="switch-wrapper">
|
||||
<bSwitch
|
||||
class="switch"
|
||||
|
@ -1,7 +1,7 @@
|
||||
<form #settingsForm="ngForm" class="form-horizontal">
|
||||
<div class="card mb-4">
|
||||
<h5 class="card-header" i18n>
|
||||
Folder indexing
|
||||
<ng-container i18n>Folder indexing</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<form #settingsForm="ngForm" class="form-horizontal">
|
||||
<div class="card mb-4">
|
||||
<h5 class="card-header">
|
||||
<ng-container i18n>Map settings</ng-container>
|
||||
<ng-container i18n>Map settings</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
<div class="switch-wrapper">
|
||||
<bSwitch
|
||||
class="switch"
|
||||
|
@ -1,7 +1,7 @@
|
||||
<form #settingsForm="ngForm" class="form-horizontal">
|
||||
<div class="card mb-4">
|
||||
<h5 class="card-header">
|
||||
<ng-container i18n>Meta file settings</ng-container>
|
||||
<ng-container i18n>Meta file settings</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
<div class="switch-wrapper">
|
||||
<bSwitch
|
||||
class="switch"
|
||||
|
@ -1,7 +1,7 @@
|
||||
<form #settingsForm="ngForm" class="form-horizontal" >
|
||||
<div class="card mb-4">
|
||||
<h5 class="card-header" i18n>
|
||||
Other settings
|
||||
<ng-container i18n>Other settings</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong i18n>Error: </strong>{{error}}</div>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="card mb-4"
|
||||
[ngClass]="settings.enabled && !_settingsService.isSupported()?'panel-warning':''">
|
||||
<h5 class="card-header">
|
||||
<ng-container i18n>Random Photo settings</ng-container>
|
||||
<ng-container i18n>Random Photo settings</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
<div class="switch-wrapper">
|
||||
<bSwitch
|
||||
class="switch"
|
||||
|
@ -44,11 +44,15 @@ export class ScheduledTasksService {
|
||||
if (this.timer != null || this.subscribers === 0) {
|
||||
return;
|
||||
}
|
||||
let repeatTime = 5000;
|
||||
if (Object.values(this.progress.value).length === 0) {
|
||||
repeatTime = 10000;
|
||||
}
|
||||
this.timer = window.setTimeout(async () => {
|
||||
await this.getProgress();
|
||||
this.timer = null;
|
||||
this.getProgressPeriodically();
|
||||
}, 5000);
|
||||
}, repeatTime);
|
||||
}
|
||||
|
||||
private incSubscribers() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="card mb-4"
|
||||
[ngClass]="settings.enabled && !_settingsService.isSupported()?'panel-warning':''">
|
||||
<h5 class="card-header">
|
||||
<ng-container i18n>Search settings</ng-container>
|
||||
<ng-container i18n>Search settings</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
<div class="switch-wrapper">
|
||||
<bSwitch
|
||||
class="switch"
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="card mb-4"
|
||||
[ngClass]="settings.enabled && !_settingsService.isSupported()?'panel-warning':''">
|
||||
<h5 class="card-header">
|
||||
<ng-container i18n>Share settings</ng-container>
|
||||
<ng-container i18n>Share settings</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
<div class="switch-wrapper">
|
||||
<bSwitch
|
||||
class="switch"
|
||||
|
@ -1,7 +1,8 @@
|
||||
<form #settingsForm="ngForm" class="form-horizontal">
|
||||
<div class="card mb-4">
|
||||
<h5 class="card-header" i18n>
|
||||
Tasks
|
||||
<ng-container i18n>Tasks</ng-container>
|
||||
<ng-container *ngIf="changed">*</ng-container>
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
@ -24,6 +25,36 @@
|
||||
[ngValue]="availableTask.Name">{{availableTask.Name}}
|
||||
</option>
|
||||
</select>
|
||||
<div class="row">
|
||||
<select class="form-control" [(ngModel)]="schedule.trigger.type"
|
||||
(ngModelChange)="taskTriggerTypeChanged($event,schedule)"
|
||||
[name]="'repeatType'+i" required>
|
||||
<option *ngFor="let taskTrigger of taskTriggerType"
|
||||
[ngValue]="taskTrigger.key">{{taskTrigger.value}}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<app-timestamp-datepicker
|
||||
[name]="'triggerTime'+i"
|
||||
*ngIf="schedule.trigger.type== TaskTriggerType.scheduled"
|
||||
[(timestamp)]="schedule.trigger.time"></app-timestamp-datepicker>
|
||||
|
||||
<select *ngIf="schedule.trigger.type== TaskTriggerType.periodic"
|
||||
class="form-control" [(ngModel)]="schedule.trigger.periodicity" [name]="'periodicity'+i"
|
||||
required>
|
||||
<option *ngFor="let period of periods; let i= index"
|
||||
[ngValue]="i">
|
||||
<ng-container i18n>every</ng-container>
|
||||
{{period}}
|
||||
</option>
|
||||
</select>
|
||||
<app-timestamp-timepicker
|
||||
[name]="'atTime'+i"
|
||||
(timestampChange)="testSettingChanges()"
|
||||
*ngIf="schedule.trigger.type== TaskTriggerType.periodic"
|
||||
[(timestamp)]="schedule.trigger.atTime"></app-timestamp-timepicker>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-success"
|
||||
@ -31,7 +62,7 @@
|
||||
[disabled]="disableButtons"
|
||||
title="Trigger task run manually"
|
||||
i18n-title
|
||||
(click)="start(schedule)" i18n>Start
|
||||
(click)="start(schedule)" i18n>Start now
|
||||
</button>
|
||||
<button class="btn btn-secondary"
|
||||
*ngIf="tasksService.progress.value[schedule.taskName]"
|
||||
@ -110,6 +141,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-success float-right"
|
||||
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
||||
(click)="save()" i18n>Save
|
||||
</button>
|
||||
<button class="btn btn-secondary float-right"
|
||||
(click)="reset()" i18n>Reset
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -8,19 +8,29 @@ import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {ErrorDTO} from '../../../../../common/entities/Error';
|
||||
import {ScheduledTasksService} from '../scheduled-tasks.service';
|
||||
import {TaskScheduleDTO} from '../../../../../common/entities/task/TaskScheduleDTO';
|
||||
import {
|
||||
NeverTaskTrigger,
|
||||
PeriodicTaskTrigger,
|
||||
ScheduledTaskTrigger,
|
||||
TaskScheduleDTO,
|
||||
TaskTriggerType
|
||||
} from '../../../../../common/entities/task/TaskScheduleDTO';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-tasks',
|
||||
templateUrl: './tasks.settings.component.html',
|
||||
styleUrls: ['./tasks.settings.component.css',
|
||||
'./../_abstract/abstract.settings.component.css'],
|
||||
providers: [TasksSettingsService],
|
||||
providers: [TasksSettingsService]
|
||||
})
|
||||
export class TasksSettingsComponent extends SettingsComponent<TaskConfig, TasksSettingsService>
|
||||
implements OnInit, OnDestroy, OnChanges {
|
||||
|
||||
disableButtons = false;
|
||||
taskTriggerType: { key: number, value: string }[];
|
||||
TaskTriggerType = TaskTriggerType;
|
||||
periods: string[] = [];
|
||||
|
||||
constructor(_authService: AuthenticationService,
|
||||
_navigation: NavigationService,
|
||||
@ -37,7 +47,15 @@ export class TasksSettingsComponent extends SettingsComponent<TaskConfig, TasksS
|
||||
i18n,
|
||||
s => s.Server.tasks);
|
||||
this.hasAvailableSettings = !this.simplifiedMode;
|
||||
|
||||
this.taskTriggerType = Utils.enumToArray(TaskTriggerType);
|
||||
this.periods = [this.i18n('Monday'),
|
||||
this.i18n('Tuesday'),
|
||||
this.i18n('Wednesday'),
|
||||
this.i18n('Thursday'),
|
||||
this.i18n('Friday'),
|
||||
this.i18n('Saturday'),
|
||||
this.i18n('Sunday'),
|
||||
this.i18n('day')];
|
||||
}
|
||||
|
||||
|
||||
@ -130,6 +148,34 @@ export class TasksSettingsComponent extends SettingsComponent<TaskConfig, TasksS
|
||||
|
||||
}
|
||||
|
||||
update($event: string, trigger: ScheduledTaskTrigger) {
|
||||
if (!$event) {
|
||||
return;
|
||||
}
|
||||
console.log(typeof $event);
|
||||
console.log($event);
|
||||
console.log(new Date($event));
|
||||
console.log(new Date($event).getTime());
|
||||
trigger.time = new Date($event).getTime();
|
||||
}
|
||||
|
||||
toDate(time: number) {
|
||||
return new Date(time);
|
||||
}
|
||||
|
||||
taskTriggerTypeChanged(triggerType: TaskTriggerType, schedule: TaskScheduleDTO) {
|
||||
schedule.trigger = <NeverTaskTrigger>{type: triggerType};
|
||||
switch (triggerType) {
|
||||
case TaskTriggerType.scheduled:
|
||||
(<ScheduledTaskTrigger><unknown>schedule.trigger).time = (Date.now());
|
||||
break;
|
||||
|
||||
case TaskTriggerType.periodic:
|
||||
(<PeriodicTaskTrigger><unknown>schedule.trigger).periodicity = null;
|
||||
(<PeriodicTaskTrigger><unknown>schedule.trigger).atTime = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<form #settingsForm="ngForm" class="form-horizontal">
|
||||
<div class="card mb-4">
|
||||
<h5 class="card-header" i18n>
|
||||
Thumbnail settings
|
||||
<ng-container i18n>Thumbnail settings</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<form #settingsForm="ngForm" class="form-horizontal">
|
||||
<div class="card mb-4">
|
||||
<h5 class="card-header">
|
||||
<ng-container i18n>Video settings</ng-container>
|
||||
<ng-container i18n>Video settings</ng-container><ng-container *ngIf="changed">*</ng-container>
|
||||
<div class="switch-wrapper">
|
||||
<bSwitch
|
||||
class="switch"
|
||||
|
@ -0,0 +1,8 @@
|
||||
<input
|
||||
class="form-control"
|
||||
[name]="name"
|
||||
bsDatepicker
|
||||
[ngModel]="date"
|
||||
(ngModelChange)="onChange($event)"
|
||||
[bsConfig]="{ dateInputFormat: 'YYYY.MM.DD, h:mm' }"
|
||||
required>
|
@ -0,0 +1,37 @@
|
||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-timestamp-datepicker',
|
||||
templateUrl: './datepicker.component.html',
|
||||
})
|
||||
export class TimeStampDatePickerComponent {
|
||||
|
||||
timestampValue = 0;
|
||||
@Output() timestampChange = new EventEmitter<number>();
|
||||
|
||||
date: Date = new Date();
|
||||
@Input() name: string;
|
||||
|
||||
@Input()
|
||||
public get timestamp() {
|
||||
return this.timestampValue;
|
||||
}
|
||||
|
||||
public set timestamp(val: number) {
|
||||
this.date.setTime(val);
|
||||
if (this.timestampValue === val) {
|
||||
return;
|
||||
}
|
||||
this.timestampValue = val;
|
||||
this.timestampChange.emit(this.timestampValue);
|
||||
}
|
||||
|
||||
onChange(date: Date | string) {
|
||||
this.timestamp = (new Date(date)).getTime();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,10 @@
|
||||
<timepicker
|
||||
class="form-control"
|
||||
[name]="name"
|
||||
[ngModel]="date"
|
||||
[showSpinners]="false"
|
||||
[showMeridian]="false"
|
||||
[mousewheel]="true"
|
||||
[arrowkeys]="true"
|
||||
(ngModelChange)="onChange($event)"
|
||||
required></timepicker>
|
@ -0,0 +1,38 @@
|
||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-timestamp-timepicker',
|
||||
templateUrl: './timepicker.component.html',
|
||||
})
|
||||
export class TimeStampTimePickerComponent {
|
||||
|
||||
timestampValue = 0;
|
||||
@Output() timestampChange = new EventEmitter<number>();
|
||||
|
||||
date: Date = new Date();
|
||||
|
||||
@Input() name: string;
|
||||
|
||||
@Input()
|
||||
public get timestamp() {
|
||||
return this.timestampValue;
|
||||
}
|
||||
|
||||
public set timestamp(val: number) {
|
||||
this.date.setTime(val);
|
||||
if (this.timestampValue === val) {
|
||||
return;
|
||||
}
|
||||
this.timestampValue = val;
|
||||
this.timestampChange.emit(this.timestampValue);
|
||||
}
|
||||
|
||||
onChange(date: Date | string) {
|
||||
this.timestamp = (new Date(date)).getTime();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
11
package-lock.json
generated
11
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "pigallery2",
|
||||
"version": "1.6.5",
|
||||
"version": "1.7.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -4536,8 +4536,7 @@
|
||||
"bootstrap": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
|
||||
"integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag==",
|
||||
"dev": true
|
||||
"integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
|
||||
},
|
||||
"boxen": {
|
||||
"version": "3.2.0",
|
||||
@ -12243,9 +12242,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"ngx-bootstrap": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ngx-bootstrap/-/ngx-bootstrap-5.1.0.tgz",
|
||||
"integrity": "sha512-gHmIH1dZcZgbgu9Y88iPa8JaMkSM1QrU1zPDSJIw5TUNXVbwhvi5bzh2ttjvL88agyVWmTHM0mgyntPAgULxCQ==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ngx-bootstrap/-/ngx-bootstrap-4.3.0.tgz",
|
||||
"integrity": "sha512-ZPS6V2yLEeqB/7KIlVohS8qUdtFa1bgUB/sSPWRcXqOWU3EKhORetZoXG6m2F5ILYDe5hwQvBEjdHPlEz2piOg==",
|
||||
"dev": true
|
||||
},
|
||||
"ngx-clipboard": {
|
||||
|
@ -29,6 +29,7 @@
|
||||
"dependencies": {
|
||||
"bcryptjs": "2.4.3",
|
||||
"body-parser": "1.19.0",
|
||||
"bootstrap": "4.1.1",
|
||||
"cookie-parser": "1.4.4",
|
||||
"cookie-session": "2.0.0-beta.3",
|
||||
"ejs": "2.6.2",
|
||||
@ -39,6 +40,7 @@
|
||||
"jdataview": "2.5.0",
|
||||
"jimp": "0.6.4",
|
||||
"locale": "0.1.0",
|
||||
"ngx-bootstrap": "^4.1.1",
|
||||
"npm-check-updates": "^3.1.20",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"sqlite3": "4.0.9",
|
||||
|
Loading…
Reference in New Issue
Block a user