Browse Source

Rename files.

pull/65/head
Sebastian Stehle 9 years ago
parent
commit
e93be2c34c
  1. 3
      src/Squidex.Events/Assets/AssetCreated.cs
  2. 3
      src/Squidex.Events/Assets/AssetUpdated.cs
  3. 4
      src/Squidex.Read.MongoDb/Assets/MongoAssetEntity.cs
  4. 4
      src/Squidex.Read/Assets/IAssetEntity.cs
  5. 4
      src/Squidex.Write/Assets/AssetCommandHandler.cs
  6. 15
      src/Squidex.Write/Assets/AssetDomainObject.cs
  7. 26
      src/Squidex/Controllers/Api/Assets/AssetContentController.cs
  8. 2
      src/Squidex/Controllers/Api/Assets/AssetController.cs
  9. 5
      src/Squidex/Controllers/Api/Assets/Models/AssetCreatedDto.cs
  10. 6
      src/Squidex/Controllers/Api/Assets/Models/AssetReplacedDto.cs
  11. 2
      src/Squidex/Controllers/Api/Assets/Models/AssetUpdateDto.cs
  12. 2
      src/Squidex/Views/Account/Error.cshtml
  13. 37
      src/Squidex/app/features/assets/pages/asset.component.html
  14. 5
      src/Squidex/app/features/assets/pages/asset.component.scss
  15. 161
      src/Squidex/app/features/assets/pages/asset.component.ts
  16. 20
      src/Squidex/app/shared/services/assets.service.ts
  17. 18
      tests/Squidex.Write.Tests/Assets/AssetCommandHandlerTests.cs
  18. 2
      tests/Squidex.Write.Tests/Assets/AssetDomainObjectTests.cs

3
src/Squidex.Events/Assets/AssetCreated.cs

@ -6,6 +6,7 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using System;
using Squidex.Infrastructure; using Squidex.Infrastructure;
namespace Squidex.Events.Assets namespace Squidex.Events.Assets
@ -17,6 +18,8 @@ namespace Squidex.Events.Assets
public string MimeType { get; set; } public string MimeType { get; set; }
public long FileVersion { get; set; }
public long FileSize { get; set; } public long FileSize { get; set; }
public bool IsImage { get; set; } public bool IsImage { get; set; }

3
src/Squidex.Events/Assets/AssetUpdated.cs

@ -6,6 +6,7 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using System;
using Squidex.Infrastructure; using Squidex.Infrastructure;
namespace Squidex.Events.Assets namespace Squidex.Events.Assets
@ -17,6 +18,8 @@ namespace Squidex.Events.Assets
public long FileSize { get; set; } public long FileSize { get; set; }
public long FileVersion { get; set; }
public bool IsImage { get; set; } public bool IsImage { get; set; }
public int? PixelWidth { get; set; } public int? PixelWidth { get; set; }

4
src/Squidex.Read.MongoDb/Assets/MongoAssetEntity.cs

@ -20,6 +20,10 @@ namespace Squidex.Read.MongoDb.Assets
[BsonElement] [BsonElement]
public long FileSize { get; set; } public long FileSize { get; set; }
[BsonRequired]
[BsonElement]
public long FileVersion { get; set; }
[BsonRequired] [BsonRequired]
[BsonElement] [BsonElement]
public bool IsImage { get; set; } public bool IsImage { get; set; }

4
src/Squidex.Read/Assets/IAssetEntity.cs

@ -6,6 +6,8 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using System;
namespace Squidex.Read.Assets namespace Squidex.Read.Assets
{ {
public interface IAssetEntity : IAppRefEntity, IEntityWithCreatedBy, IEntityWithLastModifiedBy, IEntityWithVersion public interface IAssetEntity : IAppRefEntity, IEntityWithCreatedBy, IEntityWithLastModifiedBy, IEntityWithVersion
@ -16,6 +18,8 @@ namespace Squidex.Read.Assets
long FileSize { get; } long FileSize { get; }
long FileVersion { get; }
bool IsImage { get; } bool IsImage { get; }
int? PixelWidth { get; } int? PixelWidth { get; }

4
src/Squidex.Write/Assets/AssetCommandHandler.cs

@ -44,7 +44,7 @@ namespace Squidex.Write.Assets
c.Create(command); c.Create(command);
await assetStore.UploadAsync(c.Id, c.Version, null, command.File.OpenRead()); await assetStore.UploadAsync(c.Id, 1, null, command.File.OpenRead());
context.Succeed(EntityCreatedResult.Create(c.Id, c.Version)); context.Succeed(EntityCreatedResult.Create(c.Id, c.Version));
}); });
@ -58,7 +58,7 @@ namespace Squidex.Write.Assets
c.Update(command); c.Update(command);
await assetStore.UploadAsync(c.Id, c.Version, null, command.File.OpenRead()); await assetStore.UploadAsync(c.Id, 2, null, command.File.OpenRead());
}); });
} }

15
src/Squidex.Write/Assets/AssetDomainObject.cs

@ -22,7 +22,9 @@ namespace Squidex.Write.Assets
public class AssetDomainObject : DomainObjectBase public class AssetDomainObject : DomainObjectBase
{ {
private bool isDeleted; private bool isDeleted;
private long fileVersion;
private string fileName; private string fileName;
private Guid fileId;
public bool IsDeleted public bool IsDeleted
{ {
@ -34,6 +36,11 @@ namespace Squidex.Write.Assets
get { return fileName; } get { return fileName; }
} }
public Guid FileId
{
get { return fileId; }
}
public AssetDomainObject(Guid id, int version) public AssetDomainObject(Guid id, int version)
: base(id, version) : base(id, version)
{ {
@ -41,9 +48,15 @@ namespace Squidex.Write.Assets
protected void On(AssetCreated @event) protected void On(AssetCreated @event)
{ {
fileVersion = @event.FileVersion;
fileName = @event.FileName; fileName = @event.FileName;
} }
protected void On(AssetUpdated @event)
{
fileVersion = @event.FileVersion;
}
protected void On(AssetRenamed @event) protected void On(AssetRenamed @event)
{ {
fileName = @event.FileName; fileName = @event.FileName;
@ -64,6 +77,7 @@ namespace Squidex.Write.Assets
{ {
FileName = command.File.FileName, FileName = command.File.FileName,
FileSize = command.File.FileSize, FileSize = command.File.FileSize,
FileVersion = fileVersion + 1,
MimeType = command.File.MimeType, MimeType = command.File.MimeType,
PixelWidth = command.ImageInfo?.PixelWidth, PixelWidth = command.ImageInfo?.PixelWidth,
PixelHeight = command.ImageInfo?.PixelHeight, PixelHeight = command.ImageInfo?.PixelHeight,
@ -83,6 +97,7 @@ namespace Squidex.Write.Assets
var @event = SimpleMapper.Map(command, new AssetUpdated var @event = SimpleMapper.Map(command, new AssetUpdated
{ {
FileVersion = fileVersion + 1,
FileSize = command.File.FileSize, FileSize = command.File.FileSize,
MimeType = command.File.MimeType, MimeType = command.File.MimeType,
PixelWidth = command.ImageInfo?.PixelWidth, PixelWidth = command.ImageInfo?.PixelWidth,

26
src/Squidex/Controllers/Api/Assets/AssetContentController.cs

@ -43,11 +43,11 @@ namespace Squidex.Controllers.Api.Assets
[HttpGet] [HttpGet]
[Route("assets/{id}/")] [Route("assets/{id}/")]
public async Task<IActionResult> GetAssetContent(string app, Guid id, [FromQuery] int? width = null, [FromQuery] int? height = null, [FromQuery] string mode = null) public async Task<IActionResult> GetAssetContent(string app, Guid id, [FromQuery] int version = -1, [FromQuery] int? width = null, [FromQuery] int? height = null, [FromQuery] string mode = null)
{ {
var asset = await assetRepository.FindAssetAsync(id); var asset = await assetRepository.FindAssetAsync(id);
if (asset == null) if (asset == null || asset.FileVersion < version)
{ {
return NotFound(); return NotFound();
} }
@ -60,31 +60,31 @@ namespace Squidex.Controllers.Api.Assets
try try
{ {
await assetStorage.DownloadAsync(asset.Id, asset.Version, suffix, bodyStream); await assetStorage.DownloadAsync(asset.Id, asset.FileVersion, suffix, bodyStream);
} }
catch (AssetNotFoundException) catch (AssetNotFoundException)
{ {
using (var tempStream1 = GetTempStream()) using (var sourceStream = GetTempStream())
{ {
using (var tempStream2 = GetTempStream()) using (var destinationStream = GetTempStream())
{ {
await assetStorage.DownloadAsync(asset.Id, asset.Version, null, tempStream1); await assetStorage.DownloadAsync(asset.Id, asset.FileVersion, null, sourceStream);
tempStream1.Position = 0; sourceStream.Position = 0;
await assetThumbnailGenerator.CreateThumbnailAsync(tempStream1, tempStream2, width, height, mode); await assetThumbnailGenerator.CreateThumbnailAsync(sourceStream, destinationStream, width, height, mode);
tempStream2.Position = 0; destinationStream.Position = 0;
await assetStorage.UploadAsync(asset.Id, asset.Version, suffix, tempStream2); await assetStorage.UploadAsync(asset.Id, asset.FileVersion, suffix, destinationStream);
tempStream2.Position = 0; destinationStream.Position = 0;
await tempStream2.CopyToAsync(bodyStream); await destinationStream.CopyToAsync(bodyStream);
} }
} }
} }
} }
await assetStorage.DownloadAsync(asset.Id, asset.Version, null, bodyStream); await assetStorage.DownloadAsync(asset.Id, asset.FileVersion, null, bodyStream);
}); });
} }

2
src/Squidex/Controllers/Api/Assets/AssetController.cs

@ -160,7 +160,7 @@ namespace Squidex.Controllers.Api.Assets
[ProducesResponseType(typeof(ErrorDto), 400)] [ProducesResponseType(typeof(ErrorDto), 400)]
public async Task<IActionResult> PutAsset(string app, Guid id, [FromBody] AssetUpdateDto request) public async Task<IActionResult> PutAsset(string app, Guid id, [FromBody] AssetUpdateDto request)
{ {
var command = SimpleMapper.Map(request, new RenameAsset()); var command = SimpleMapper.Map(request, new RenameAsset { AssetId = id });
await CommandBus.PublishAsync(command); await CommandBus.PublishAsync(command);

5
src/Squidex/Controllers/Api/Assets/Models/AssetCreatedDto.cs

@ -37,6 +37,11 @@ namespace Squidex.Controllers.Api.Assets.Models
/// </summary> /// </summary>
public long FileSize { get; set; } public long FileSize { get; set; }
/// <summary>
/// The version of the file.
/// </summary>
public long FileVersion { get; set; }
/// <summary> /// <summary>
/// Determines of the created file is an image. /// Determines of the created file is an image.
/// </summary> /// </summary>

6
src/Squidex/Controllers/Api/Assets/Models/AssetReplacedDto.cs

@ -25,6 +25,11 @@ namespace Squidex.Controllers.Api.Assets.Models
/// </summary> /// </summary>
public long FileSize { get; set; } public long FileSize { get; set; }
/// <summary>
/// The version of the file.
/// </summary>
public long FileVersion { get; set; }
/// <summary> /// <summary>
/// Determines of the created file is an image. /// Determines of the created file is an image.
/// </summary> /// </summary>
@ -50,6 +55,7 @@ namespace Squidex.Controllers.Api.Assets.Models
var response = new AssetReplacedDto var response = new AssetReplacedDto
{ {
FileSize = command.File.FileSize, FileSize = command.File.FileSize,
FileVersion = result.Version,
MimeType = command.File.MimeType, MimeType = command.File.MimeType,
IsImage = command.ImageInfo != null, IsImage = command.ImageInfo != null,
PixelWidth = command.ImageInfo?.PixelWidth, PixelWidth = command.ImageInfo?.PixelWidth,

2
src/Squidex/Controllers/Api/Assets/Models/AssetUpdateDto.cs

@ -16,6 +16,6 @@ namespace Squidex.Controllers.Api.Assets.Models
/// The new name of the asset. /// The new name of the asset.
/// </summary> /// </summary>
[Required] [Required]
public string Name { get; set; } public string FileName { get; set; }
} }
} }

2
src/Squidex/Views/Account/Error.cshtml

@ -5,5 +5,5 @@
<h1 class="splash-h1">Login failed</h1> <h1 class="splash-h1">Login failed</h1>
<p class="splash-text"> <p class="splash-text">
We are really sorry, something failed when you tried to login. We are really sorry, something went wrong when you tried to login.
</p> </p>

37
src/Squidex/app/features/assets/pages/asset.component.html

@ -17,6 +17,9 @@
<div class="file-overlay"> <div class="file-overlay">
<div class="file-overlay-background"></div> <div class="file-overlay-background"></div>
<a class="file-edit" (click)="renameDialog.show()">
<i class="icon-pencil"></i>
</a>
<a class="file-download" [attr.href]="downloadUrl" target="_blank"> <a class="file-download" [attr.href]="downloadUrl" target="_blank">
<i class="icon-download"></i> <i class="icon-download"></i>
</a> </a>
@ -38,7 +41,7 @@
</div> </div>
</div> </div>
<div class="card-footer"> <div class="card-footer">
<div class="file-name"> <div class="file-name" [attr.title]="fileName">
{{fileName}} {{fileName}}
</div> </div>
<div class="file-info"> <div class="file-info">
@ -55,4 +58,36 @@
<span class="drop-overlay-text">Drop to update</span> <span class="drop-overlay-text">Drop to update</span>
</div> </div>
</div> </div>
</div>
<div class="modal" *sqxModalView="renameDialog" [@fade]>
<div class="modal-backdrop"></div>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Rename asset</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="resetRename()">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form [formGroup]="renameForm" (ngSubmit)="renameAsset()">
<div class="form-group">
<label for="asset-name">Name</label>
<sqx-control-errors for="name" [submitted]="renameFormSubmitted"></sqx-control-errors>
<input type="text" class="form-control" id="asset-name" formControlName="name" autocomplete="off" sqxFocusOnInit />
</div>
<div class="form-group clearfix">
<button type="reset" class="float-left btn btn-secondary" (click)="resetRename()">Cancel</button>
<button type="submit" class="float-right btn btn-success">Rename</button>
</div>
</form>
</div>
</div>
</div>
</div> </div>

5
src/Squidex/app/features/assets/pages/asset.component.scss

@ -131,6 +131,11 @@ $card-size: 240px;
@include absolute(.5rem, 1rem, auto, auto); @include absolute(.5rem, 1rem, auto, auto);
} }
&-edit {
@include asset-link;
@include absolute(.5rem, 4rem, auto, auto);
}
&-download { &-download {
@include asset-link; @include asset-link;
@include absolute(.5rem, 2.5rem, auto, auto); @include absolute(.5rem, 2.5rem, auto, auto);

161
src/Squidex/app/features/assets/pages/asset.component.ts

@ -6,6 +6,7 @@
*/ */
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { import {
ApiUrlConfig, ApiUrlConfig,
@ -18,8 +19,10 @@ import {
AuthService, AuthService,
DateTime, DateTime,
fadeAnimation, fadeAnimation,
ModalView,
MathHelper, MathHelper,
NotificationService, NotificationService,
UpdateAssetDto,
UsersProviderService, UsersProviderService,
Version Version
} from 'shared'; } from 'shared';
@ -33,10 +36,20 @@ import {
] ]
}) })
export class AssetComponent extends AppComponentBase implements OnInit { export class AssetComponent extends AppComponentBase implements OnInit {
private assetUrlVersion = MathHelper.guid(); private cacheBuster = MathHelper.guid();
private retries = 0; private previewRetries = 0;
private version: Version; private version: Version;
public renameDialog = new ModalView();
public renameFormSubmitted = false;
public renameForm: FormGroup =
this.formBuilder.group({
name: ['',
[
Validators.required
]]
});
@Input() @Input()
public initFile: File; public initFile: File;
@ -55,11 +68,11 @@ export class AssetComponent extends AppComponentBase implements OnInit {
public progress = 0; public progress = 0;
public get previewUrl(): string { public get previewUrl(): string {
return this.apiUrl.buildUrl(`api/assets/${this.asset.id}/?width=230&height=155&mode=Crop&q=${this.assetUrlVersion}`); return this.apiUrl.buildUrl(`api/assets/${this.asset.id}/?width=230&height=155&mode=Crop&version=${this.version.value}&q=${this.cacheBuster}`);
} }
public get downloadUrl(): string { public get downloadUrl(): string {
return this.apiUrl.buildUrl(`api/assets/${this.asset.id}/?q=${this.assetUrlVersion}`); return this.apiUrl.buildUrl(`api/assets/${this.asset.id}/?q=${this.cacheBuster}`);
} }
public get fileType(): string { public get fileType(): string {
@ -89,6 +102,7 @@ export class AssetComponent extends AppComponentBase implements OnInit {
} }
constructor(apps: AppsStoreService, notifications: NotificationService, users: UsersProviderService, constructor(apps: AppsStoreService, notifications: NotificationService, users: UsersProviderService,
private readonly formBuilder: FormBuilder,
private readonly assetsService: AssetsService, private readonly assetsService: AssetsService,
private readonly authService: AuthService, private readonly authService: AuthService,
private readonly apiUrl: ApiUrlConfig private readonly apiUrl: ApiUrlConfig
@ -104,29 +118,24 @@ export class AssetComponent extends AppComponentBase implements OnInit {
.switchMap(app => this.assetsService.uploadFile(app, initFile)) .switchMap(app => this.assetsService.uploadFile(app, initFile))
.subscribe(result => { .subscribe(result => {
if (result instanceof AssetCreatedDto) { if (result instanceof AssetCreatedDto) {
setTimeout(() => { const me = `subject:${this.authService.user!.id}`;
const me = `subject:${this.authService.user!.id}`;
const asset = new AssetDto(
const asset = new AssetDto( result.id,
result.id, me, me,
me, me, DateTime.now(),
DateTime.now(), DateTime.now(),
DateTime.now(), result.fileName,
result.fileName, result.fileSize,
result.fileSize, result.fileVersion,
result.mimeType, result.mimeType,
result.isImage, result.isImage,
result.pixelWidth, result.pixelWidth,
result.pixelHeight, result.pixelHeight,
result.version); result.version);
this.updateAsset(asset);
this.asset = asset;
this.assetUrlVersion = MathHelper.guid(); this.loaded.emit(asset);
this.version = result.version;
this.progress = 0;
this.loaded.emit(asset);
}, 500);
} else { } else {
this.progress = result; this.progress = result;
} }
@ -136,7 +145,7 @@ export class AssetComponent extends AppComponentBase implements OnInit {
this.notifyError(error); this.notifyError(error);
}); });
} else { } else {
this.version = this.asset.version; this.updateAsset(this.asset);
} }
} }
@ -146,26 +155,21 @@ export class AssetComponent extends AppComponentBase implements OnInit {
.switchMap(app => this.assetsService.replaceFile(app, this.asset.id, files[0], this.version)) .switchMap(app => this.assetsService.replaceFile(app, this.asset.id, files[0], this.version))
.subscribe(result => { .subscribe(result => {
if (result instanceof AssetReplacedDto) { if (result instanceof AssetReplacedDto) {
setTimeout(() => { const me = `subject:${this.authService.user!.id}`;
const me = `subject:${this.authService.user!.id}`;
const asset = new AssetDto(
const asset = new AssetDto( this.asset.id,
this.asset.id, this.asset.createdBy, me,
this.asset.createdBy, me, this.asset.created, DateTime.now(),
this.asset.created, DateTime.now(), this.asset.fileName,
this.asset.fileName, result.fileSize,
result.fileSize, result.fileVersion,
result.mimeType, result.mimeType,
result.isImage, result.isImage,
result.pixelWidth, result.pixelWidth,
result.pixelHeight, result.pixelHeight,
result.version); result.version);
this.updateAsset(asset);
this.asset = asset;
this.assetUrlVersion = MathHelper.guid();
this.progress = 0;
this.retries = 0;
}, 500);
} else { } else {
this.progress = result; this.progress = result;
} }
@ -177,13 +181,66 @@ export class AssetComponent extends AppComponentBase implements OnInit {
} }
} }
public renameAsset() {
this.renameFormSubmitted = true;
if (this.renameForm.valid) {
this.renameForm.disable();
const dto = new UpdateAssetDto(this.renameForm.controls['name'].value);
this.appName()
.switchMap(app => this.assetsService.updateAsset(app, this.asset.id, dto, this.version))
.subscribe(_ => {
const me = `subject:${this.authService.user!.id}`;
const asset = new AssetDto(
this.asset.id,
this.asset.createdBy, me,
this.asset.created, DateTime.now(),
dto.fileName,
this.asset.fileSize,
this.asset.fileVersion,
this.asset.mimeType,
this.asset.isImage,
this.asset.pixelWidth,
this.asset.pixelHeight,
this.asset.version);
this.updateAsset(asset);
this.resetRename();
}, error => {
this.notifyError(error);
this.resetRename();
});
this.resetRename();
}
}
private resetRename() {
this.renameForm.enable();
this.renameForm.controls['name'].setValue(this.asset.fileName);
this.renameFormSubmitted = false;
this.renameDialog.hide();
}
private updateAsset(asset: AssetDto) {
this.asset = asset;
this.cacheBuster = MathHelper.guid();
this.progress = 0;
this.previewRetries = 0;
this.version = asset.version;
this.resetRename();
}
public retryLoadingImage() { public retryLoadingImage() {
this.retries++; this.previewRetries++;
if (this.retries <= 10) { if (this.previewRetries <= 10) {
setTimeout(() => { setTimeout(() => {
this.assetUrlVersion = MathHelper.guid(); this.cacheBuster = MathHelper.guid();
}, this.retries * 1000); }, this.previewRetries * 1000);
} }
} }
} }

20
src/Squidex/app/shared/services/assets.service.ts

@ -35,6 +35,7 @@ export class AssetDto {
public readonly lastModified: DateTime, public readonly lastModified: DateTime,
public readonly fileName: string, public readonly fileName: string,
public readonly fileSize: number, public readonly fileSize: number,
public readonly fileVersion: number,
public readonly mimeType: string, public readonly mimeType: string,
public readonly isImage: boolean, public readonly isImage: boolean,
public readonly pixelWidth: number | null, public readonly pixelWidth: number | null,
@ -44,11 +45,19 @@ export class AssetDto {
} }
} }
export class UpdateAssetDto {
constructor(
public readonly fileName: string
) {
}
}
export class AssetCreatedDto { export class AssetCreatedDto {
constructor( constructor(
public readonly id: string, public readonly id: string,
public readonly fileName: string, public readonly fileName: string,
public readonly fileSize: number, public readonly fileSize: number,
public readonly fileVersion: number,
public readonly mimeType: string, public readonly mimeType: string,
public readonly isImage: boolean, public readonly isImage: boolean,
public readonly pixelWidth: number | null, public readonly pixelWidth: number | null,
@ -61,6 +70,7 @@ export class AssetCreatedDto {
export class AssetReplacedDto { export class AssetReplacedDto {
constructor( constructor(
public readonly fileSize: number, public readonly fileSize: number,
public readonly fileVersion: number,
public readonly mimeType: string, public readonly mimeType: string,
public readonly isImage: boolean, public readonly isImage: boolean,
public readonly pixelWidth: number | null, public readonly pixelWidth: number | null,
@ -124,6 +134,7 @@ export class AssetsService {
DateTime.parseISO_UTC(item.lastModified), DateTime.parseISO_UTC(item.lastModified),
item.fileName, item.fileName,
item.fileSize, item.fileSize,
item.fileVersion,
item.mimeType, item.mimeType,
item.isImage, item.isImage,
item.pixelWidth, item.pixelWidth,
@ -153,6 +164,7 @@ export class AssetsService {
response.id, response.id,
response.fileName, response.fileName,
response.fileSize, response.fileSize,
response.fileVersion,
response.mimeType, response.mimeType,
response.isImage, response.isImage,
response.pixelWidth, response.pixelWidth,
@ -191,6 +203,7 @@ export class AssetsService {
.map(response => { .map(response => {
return new AssetReplacedDto( return new AssetReplacedDto(
response.fileSize, response.fileSize,
response.fileVersion,
response.mimeType, response.mimeType,
response.isImage, response.isImage,
response.pixelWidth, response.pixelWidth,
@ -208,6 +221,13 @@ export class AssetsService {
}); });
} }
public updateAsset(appName: string, id: string, dto: UpdateAssetDto, version: Version): Observable<any> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/assets/${id}`);
return this.authService.authPut(url, dto, version)
.catchError('Failed to delete asset. Please reload.');
}
public deleteAsset(appName: string, id: string, version: Version): Observable<any> { public deleteAsset(appName: string, id: string, version: Version): Observable<any> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/assets/${id}`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/assets/${id}`);

18
tests/Squidex.Write.Tests/Assets/AssetCommandHandlerTests.cs

@ -44,8 +44,8 @@ namespace Squidex.Write.Assets
[Fact] [Fact]
public async Task Create_should_create_asset() public async Task Create_should_create_asset()
{ {
assetStore.Setup(x => x.UploadAsync(assetId, 0, null, stream)).Returns(TaskHelper.Done).Verifiable(); SetupStore(1);
assetThumbnailGenerator.Setup(x => x.GetImageInfoAsync(stream)).Returns(Task.FromResult(image)).Verifiable(); SetupImageInfo();
var context = CreateContextForCommand(new CreateAsset { AssetId = assetId, File = file }); var context = CreateContextForCommand(new CreateAsset { AssetId = assetId, File = file });
@ -63,8 +63,8 @@ namespace Squidex.Write.Assets
[Fact] [Fact]
public async Task Update_should_update_domain_object() public async Task Update_should_update_domain_object()
{ {
assetStore.Setup(x => x.UploadAsync(assetId, 1, null, stream)).Returns(TaskHelper.Done).Verifiable(); SetupStore(2);
assetThumbnailGenerator.Setup(x => x.GetImageInfoAsync(stream)).Returns(Task.FromResult(image)).Verifiable(); SetupImageInfo();
CreateAsset(); CreateAsset();
@ -109,5 +109,15 @@ namespace Squidex.Write.Assets
{ {
asset.Create(new CreateAsset { File = file }); asset.Create(new CreateAsset { File = file });
} }
private void SetupImageInfo()
{
assetThumbnailGenerator.Setup(x => x.GetImageInfoAsync(stream)).Returns(Task.FromResult(image)).Verifiable();
}
private void SetupStore(long version)
{
assetStore.Setup(x => x.UploadAsync(assetId, version, null, stream)).Returns(TaskHelper.Done).Verifiable();
}
} }
} }

2
tests/Squidex.Write.Tests/Assets/AssetDomainObjectTests.cs

@ -56,6 +56,7 @@ namespace Squidex.Write.Assets
IsImage = true, IsImage = true,
FileName = file.FileName, FileName = file.FileName,
FileSize = file.FileSize, FileSize = file.FileSize,
FileVersion = 1,
MimeType = file.MimeType, MimeType = file.MimeType,
PixelWidth = image.PixelWidth, PixelWidth = image.PixelWidth,
PixelHeight = image.PixelHeight PixelHeight = image.PixelHeight
@ -97,6 +98,7 @@ namespace Squidex.Write.Assets
{ {
IsImage = true, IsImage = true,
FileSize = file.FileSize, FileSize = file.FileSize,
FileVersion = 2,
MimeType = file.MimeType, MimeType = file.MimeType,
PixelWidth = image.PixelWidth, PixelWidth = image.PixelWidth,
PixelHeight = image.PixelHeight PixelHeight = image.PixelHeight

Loading…
Cancel
Save