mirror of https://github.com/Squidex/squidex.git
22 changed files with 241 additions and 48 deletions
@ -1,18 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using Squidex.Infrastructure.EventSourcing; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Events.Contents |
|
||||
{ |
|
||||
[EventType(nameof(ContentStatusChanged))] |
|
||||
public sealed class ContentScheduleItemRemoved : ContentEvent |
|
||||
{ |
|
||||
public Guid ScheduleItemId { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,34 @@ |
|||||
|
<sqx-title message="{app} | Backups | Settings" parameter1="app" [value1]="ctx.appName"></sqx-title> |
||||
|
|
||||
|
<sqx-panel desiredWidth="50rem"> |
||||
|
<div class="panel-header"> |
||||
|
<div class="panel-title-row"> |
||||
|
<div class="float-right"> |
||||
|
<button class="btn btn-success" (click)="startBackup()"> |
||||
|
Start Backup |
||||
|
</button> |
||||
|
</div> |
||||
|
|
||||
|
<h3 class="panel-title">Backups</h3> |
||||
|
</div> |
||||
|
|
||||
|
<a class="panel-close" sqxParentLink> |
||||
|
<i class="icon-close"></i> |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-main"> |
||||
|
<div class="panel-content"> |
||||
|
<table class="table table-items table-fixed"> |
||||
|
<tbody> |
||||
|
<ng-template ngFor let-backup [ngForOf]="backups | async"> |
||||
|
<tr> |
||||
|
<td>{{backup.started | sqxFullDateTime }}</td> |
||||
|
</tr> |
||||
|
<tr class="spacer"></tr> |
||||
|
</ng-template> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</sqx-panel> |
||||
@ -0,0 +1,2 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
@ -0,0 +1,49 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
||||
|
*/ |
||||
|
|
||||
|
import { Component } from '@angular/core'; |
||||
|
import { Observable } from 'rxjs'; |
||||
|
|
||||
|
import { AppContext, BackupsService } from 'shared'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'sqx-backups-page', |
||||
|
styleUrls: ['./backups-page.component.scss'], |
||||
|
templateUrl: './backups-page.component.html', |
||||
|
providers: [ |
||||
|
AppContext |
||||
|
] |
||||
|
}) |
||||
|
export class BackupsPageComponent { |
||||
|
public backups = |
||||
|
Observable.timer(0, 5000) |
||||
|
.switchMap(t => this.backupsService.getBackups(this.ctx.appName)); |
||||
|
|
||||
|
constructor(public readonly ctx: AppContext, |
||||
|
private readonly backupsService: BackupsService |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public startBackup() { |
||||
|
this.backupsService.postBackup(this.ctx.appName) |
||||
|
.subscribe(() => { |
||||
|
this.ctx.notifyInfo('Backup started.'); |
||||
|
}, error => { |
||||
|
this.ctx.notifyError(error); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public deleteBackup(id: string) { |
||||
|
this.backupsService.deleteBackup(this.ctx.appName, id) |
||||
|
.subscribe(() => { |
||||
|
this.ctx.notifyInfo('Backup deleting.'); |
||||
|
}, error => { |
||||
|
this.ctx.notifyError(error); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,76 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
||||
|
*/ |
||||
|
|
||||
|
import { HttpClient } from '@angular/common/http'; |
||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { Observable } from 'rxjs'; |
||||
|
|
||||
|
import 'framework/angular/http-extensions'; |
||||
|
|
||||
|
import { |
||||
|
AnalyticsService, |
||||
|
ApiUrlConfig, |
||||
|
DateTime |
||||
|
} from 'framework'; |
||||
|
|
||||
|
export class BackupDto { |
||||
|
constructor( |
||||
|
public readonly id: string, |
||||
|
public readonly isFailed: string, |
||||
|
public readonly started: DateTime, |
||||
|
public readonly stopped: DateTime | null |
||||
|
) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Injectable() |
||||
|
export class BackupsService { |
||||
|
constructor( |
||||
|
private readonly http: HttpClient, |
||||
|
private readonly apiUrl: ApiUrlConfig, |
||||
|
private readonly analytics: AnalyticsService |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public getBackups(appName: string): Observable<BackupDto[]> { |
||||
|
const url = this.apiUrl.buildUrl(`api/apps/${appName}/backups`); |
||||
|
|
||||
|
return this.http.get(url) |
||||
|
.map(response => { |
||||
|
const items: any[] = <any>response; |
||||
|
|
||||
|
return items.map(item => { |
||||
|
return new BackupDto( |
||||
|
item.id, |
||||
|
item.isFailed, |
||||
|
DateTime.parseISO_UTC(item.stopped), |
||||
|
item.stopped ? DateTime.parseISO_UTC(item.stopped) : null); |
||||
|
}); |
||||
|
}) |
||||
|
.pretifyError('Failed to load backups.'); |
||||
|
} |
||||
|
|
||||
|
public postBackup(appName: string): Observable<any> { |
||||
|
const url = this.apiUrl.buildUrl(`api/apps/${appName}/backups`); |
||||
|
|
||||
|
return this.http.post(url, {}) |
||||
|
.do(() => { |
||||
|
this.analytics.trackEvent('Backup', 'Started', appName); |
||||
|
}) |
||||
|
.pretifyError('Failed to start backup.'); |
||||
|
} |
||||
|
|
||||
|
public deleteBackup(appName: string, id: string): Observable<any> { |
||||
|
const url = this.apiUrl.buildUrl(`api/apps/${appName}/backups/${id}`); |
||||
|
|
||||
|
return this.http.delete(url) |
||||
|
.do(() => { |
||||
|
this.analytics.trackEvent('Backup', 'Deleted', appName); |
||||
|
}) |
||||
|
.pretifyError('Failed to delete backup.'); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue