mirror of https://github.com/Squidex/squidex.git
21 changed files with 330 additions and 113 deletions
@ -0,0 +1,26 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
||||
|
*/ |
||||
|
|
||||
|
import { Pipe, PipeTransform } from '@angular/core'; |
||||
|
|
||||
|
@Pipe({ |
||||
|
name: 'sqxRuleEventBadgeClass', |
||||
|
pure: true |
||||
|
}) |
||||
|
export class RuleEventBadgeClassPipe implements PipeTransform { |
||||
|
public transform(status: string) { |
||||
|
if (status === 'Retry') { |
||||
|
return 'warning'; |
||||
|
} else if (status === 'Failed') { |
||||
|
return 'danger'; |
||||
|
} else if (status === 'Pending') { |
||||
|
return 'secondary'; |
||||
|
} else { |
||||
|
return status.toLowerCase(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
||||
|
*/ |
||||
|
|
||||
|
import { Pipe, PipeTransform } from '@angular/core'; |
||||
|
|
||||
|
import { |
||||
|
ApiUrlConfig, |
||||
|
AppsState, |
||||
|
BackupDto, |
||||
|
Duration |
||||
|
} from '@app/shared'; |
||||
|
|
||||
|
@Pipe({ |
||||
|
name: 'sqxBackupDuration', |
||||
|
pure: true |
||||
|
}) |
||||
|
export class BackupDurationPipe implements PipeTransform { |
||||
|
public transform(backup: BackupDto) { |
||||
|
return Duration.create(backup.started, backup.stopped!).toString(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Pipe({ |
||||
|
name: 'sqxBackupDownloadUrl', |
||||
|
pure: true |
||||
|
}) |
||||
|
export class BackupDownloadUrlPipe implements PipeTransform { |
||||
|
constructor( |
||||
|
private readonly apiUrl: ApiUrlConfig, |
||||
|
private readonly appsState: AppsState |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public transform(backup: BackupDto) { |
||||
|
return this.apiUrl.buildUrl(`api/apps/${this.appsState.appName}/backups/${backup.id}`); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,75 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
||||
|
*/ |
||||
|
|
||||
|
import { Observable } from 'rxjs'; |
||||
|
import { IMock, It, Mock, Times } from 'typemoq'; |
||||
|
|
||||
|
import { |
||||
|
AppsState, |
||||
|
BackupDto, |
||||
|
BackupsState, |
||||
|
BackupsService, |
||||
|
DateTime, |
||||
|
DialogService |
||||
|
} from '@app/shared'; |
||||
|
|
||||
|
describe('BackupsState', () => { |
||||
|
const app = 'my-app'; |
||||
|
|
||||
|
const oldBackups = [ |
||||
|
new BackupDto('id1', DateTime.now(), null, 1, 1, false), |
||||
|
new BackupDto('id2', DateTime.now(), null, 2, 2, false) |
||||
|
]; |
||||
|
|
||||
|
let dialogs: IMock<DialogService>; |
||||
|
let appsState: IMock<AppsState>; |
||||
|
let backupsService: IMock<BackupsService>; |
||||
|
let backupsState: BackupsState; |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
dialogs = Mock.ofType<DialogService>(); |
||||
|
|
||||
|
appsState = Mock.ofType<AppsState>(); |
||||
|
|
||||
|
appsState.setup(x => x.appName) |
||||
|
.returns(() => app); |
||||
|
|
||||
|
backupsService = Mock.ofType<BackupsService>(); |
||||
|
|
||||
|
backupsService.setup(x => x.getBackups(app)) |
||||
|
.returns(() => Observable.of(oldBackups)); |
||||
|
|
||||
|
backupsState = new BackupsState(appsState.object, backupsService.object, dialogs.object); |
||||
|
backupsState.load().subscribe(); |
||||
|
}); |
||||
|
|
||||
|
it('should load clients', () => { |
||||
|
expect(backupsState.snapshot.backups.values).toEqual(oldBackups); |
||||
|
}); |
||||
|
|
||||
|
it('should not add backup to snapshot', () => { |
||||
|
backupsService.setup(x => x.postBackup(app)) |
||||
|
.returns(() => Observable.of({})); |
||||
|
|
||||
|
backupsState.start().subscribe(); |
||||
|
|
||||
|
expect(backupsState.snapshot.backups.length).toBe(2); |
||||
|
|
||||
|
dialogs.verify(x => x.notifyInfo(It.isAnyString()), Times.once()); |
||||
|
}); |
||||
|
|
||||
|
it('should not remove backup from snapshot', () => { |
||||
|
backupsService.setup(x => x.deleteBackup(app, oldBackups[0].id)) |
||||
|
.returns(() => Observable.of({})); |
||||
|
|
||||
|
backupsState.delete(oldBackups[0]).subscribe(); |
||||
|
|
||||
|
expect(backupsState.snapshot.backups.length).toBe(2); |
||||
|
|
||||
|
dialogs.verify(x => x.notifyInfo(It.isAnyString()), Times.once()); |
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,69 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
||||
|
*/ |
||||
|
|
||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { Observable } from 'rxjs'; |
||||
|
|
||||
|
import '@app/framework/utils/rxjs-extensions'; |
||||
|
|
||||
|
import { |
||||
|
DialogService, |
||||
|
ImmutableArray, |
||||
|
State |
||||
|
} from '@app/framework'; |
||||
|
|
||||
|
import { AppsState } from './apps.state'; |
||||
|
|
||||
|
import { BackupDto, BackupsService } from './../services/backups.service'; |
||||
|
|
||||
|
interface Snapshot { |
||||
|
backups: ImmutableArray<BackupDto>; |
||||
|
} |
||||
|
|
||||
|
@Injectable() |
||||
|
export class BackupsState extends State<Snapshot> { |
||||
|
public backups = |
||||
|
this.changes.map(x => x.backups); |
||||
|
|
||||
|
public maxBackupsReached = |
||||
|
this.changes.map(x => x.backups.length >= 10); |
||||
|
|
||||
|
constructor( |
||||
|
private readonly appsState: AppsState, |
||||
|
private readonly backupsService: BackupsService, |
||||
|
private readonly dialogs: DialogService |
||||
|
) { |
||||
|
super({ backups: ImmutableArray.empty() }); |
||||
|
} |
||||
|
|
||||
|
public load(): Observable<any> { |
||||
|
return this.backupsService.getBackups(this.appName) |
||||
|
.do(dtos => { |
||||
|
this.next({ backups: ImmutableArray.of(dtos) }); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public start(): Observable<any> { |
||||
|
return this.backupsService.postBackup(this.appsState.appName) |
||||
|
.do(() => { |
||||
|
this.dialogs.notifyInfo('Backup started, it can take several minutes to complete.'); |
||||
|
}) |
||||
|
.notify(this.dialogs); |
||||
|
} |
||||
|
|
||||
|
public delete(backup: BackupDto): Observable<any> { |
||||
|
return this.backupsService.deleteBackup(this.appsState.appName, backup.id) |
||||
|
.do(() => { |
||||
|
this.dialogs.notifyInfo('Backup is about to be deleted.'); |
||||
|
}) |
||||
|
.notify(this.dialogs); |
||||
|
} |
||||
|
|
||||
|
private get appName() { |
||||
|
return this.appsState.appName; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue