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