diff --git a/src/Squidex/Controllers/Api/Assets/AssetController.cs b/src/Squidex/Controllers/Api/Assets/AssetController.cs index 7d4e4b9b2..e19fe9716 100644 --- a/src/Squidex/Controllers/Api/Assets/AssetController.cs +++ b/src/Squidex/Controllers/Api/Assets/AssetController.cs @@ -90,7 +90,7 @@ namespace Squidex.Controllers.Api.Assets } /// - /// Creates and uploads a new asset. + /// Upload a new asset. /// /// The app where the asset is a part of. /// The file to upload. @@ -101,7 +101,7 @@ namespace Squidex.Controllers.Api.Assets /// [HttpPost] [Route("apps/{app}/assets/")] - [ProducesResponseType(typeof(AssetDto), 201)] + [ProducesResponseType(typeof(AssetCreatedDto), 201)] [ProducesResponseType(typeof(ErrorDto), 400)] public async Task PostAsset(string app, List file) { @@ -111,13 +111,13 @@ namespace Squidex.Controllers.Api.Assets var context = await CommandBus.PublishAsync(command); var result = context.Result>(); - var response = AssetDto.Create(command, result); + var response = AssetCreatedDto.Create(command, result); return StatusCode(201, response); } /// - /// Replaces the content of the asset with a newer version. + /// Replace asset content. /// /// The app where the asset is a part of. /// The id of the asset. @@ -129,7 +129,7 @@ namespace Squidex.Controllers.Api.Assets /// [HttpPut] [Route("apps/{app}/assets/{id}/content")] - [ProducesResponseType(typeof(AssetDto), 201)] + [ProducesResponseType(typeof(AssetReplacedDto), 201)] [ProducesResponseType(typeof(ErrorDto), 400)] public async Task PutAssetContent(string app, Guid id, List file) { @@ -139,7 +139,7 @@ namespace Squidex.Controllers.Api.Assets var context = await CommandBus.PublishAsync(command); var result = context.Result(); - var response = AssetUpdatedDto.Create(command, result); + var response = AssetReplacedDto.Create(command, result); return StatusCode(201, response); } @@ -152,6 +152,7 @@ namespace Squidex.Controllers.Api.Assets /// The asset object that needs to updated. /// /// 204 => Asset updated. + /// 400 => Asset name not valid. /// 404 => Asset or app not found. /// [HttpPut] diff --git a/src/Squidex/Controllers/Api/Assets/Models/AssetUpdatedDto.cs b/src/Squidex/Controllers/Api/Assets/Models/AssetCreatedDto.cs similarity index 71% rename from src/Squidex/Controllers/Api/Assets/Models/AssetUpdatedDto.cs rename to src/Squidex/Controllers/Api/Assets/Models/AssetCreatedDto.cs index 1010b7acb..1f847b880 100644 --- a/src/Squidex/Controllers/Api/Assets/Models/AssetUpdatedDto.cs +++ b/src/Squidex/Controllers/Api/Assets/Models/AssetCreatedDto.cs @@ -1,21 +1,31 @@ // ========================================================================== -// AssetUpdatedDto.cs +// AssetDto.cs // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex Group // All rights reserved. // ========================================================================== +using System; using System.ComponentModel.DataAnnotations; -using NodaTime; -using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS.Commands; using Squidex.Write.Assets.Commands; namespace Squidex.Controllers.Api.Assets.Models { - public sealed class AssetUpdatedDto + public sealed class AssetCreatedDto { + /// + /// The id of the asset. + /// + public Guid Id { get; set; } + + /// + /// The file name. + /// + [Required] + public string FileName { get; set; } + /// /// The mime type. /// @@ -42,36 +52,23 @@ namespace Squidex.Controllers.Api.Assets.Models /// public int? PixelHeight { get; set; } - /// - /// The user that has updated the asset. - /// - [Required] - public RefToken LastModifiedBy { get; set; } - - /// - /// The date and time when the asset has been modified last. - /// - public Instant LastModified { get; set; } - /// /// The version of the asset. /// public long Version { get; set; } - public static AssetUpdatedDto Create(UpdateAsset command, EntitySavedResult result) + public static AssetCreatedDto Create(CreateAsset command, EntityCreatedResult result) { - var now = SystemClock.Instance.GetCurrentInstant(); - - var response = new AssetUpdatedDto + var response = new AssetCreatedDto { - Version = result.Version, - LastModified = now, - LastModifiedBy = command.Actor, + Id = command.AssetId, + FileName = command.File.FileName, FileSize = command.File.FileSize, MimeType = command.File.MimeType, IsImage = command.ImageInfo != null, PixelWidth = command.ImageInfo?.PixelWidth, - PixelHeight = command.ImageInfo?.PixelHeight + PixelHeight = command.ImageInfo?.PixelHeight, + Version = result.Version }; return response; diff --git a/src/Squidex/Controllers/Api/Assets/Models/AssetDto.cs b/src/Squidex/Controllers/Api/Assets/Models/AssetDto.cs index 21d5dbf5e..b60294929 100644 --- a/src/Squidex/Controllers/Api/Assets/Models/AssetDto.cs +++ b/src/Squidex/Controllers/Api/Assets/Models/AssetDto.cs @@ -10,8 +10,6 @@ using System; using System.ComponentModel.DataAnnotations; using NodaTime; using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Commands; -using Squidex.Write.Assets.Commands; namespace Squidex.Controllers.Api.Assets.Models { @@ -80,28 +78,5 @@ namespace Squidex.Controllers.Api.Assets.Models /// The version of the asset. /// public long Version { get; set; } - - public static AssetDto Create(CreateAsset command, EntityCreatedResult result) - { - var now = SystemClock.Instance.GetCurrentInstant(); - - var response = new AssetDto - { - Id = result.IdOrValue, - Version = result.Version, - Created = now, - CreatedBy = command.Actor, - LastModified = now, - LastModifiedBy = command.Actor, - FileName = command.File.FileName, - FileSize = command.File.FileSize, - MimeType = command.File.MimeType, - IsImage = command.ImageInfo != null, - PixelWidth = command.ImageInfo?.PixelWidth, - PixelHeight = command.ImageInfo?.PixelHeight - }; - - return response; - } } } diff --git a/src/Squidex/Controllers/Api/Assets/Models/AssetReplacedDto.cs b/src/Squidex/Controllers/Api/Assets/Models/AssetReplacedDto.cs new file mode 100644 index 000000000..0031c697a --- /dev/null +++ b/src/Squidex/Controllers/Api/Assets/Models/AssetReplacedDto.cs @@ -0,0 +1,63 @@ +// ========================================================================== +// AssetUpdatedDto.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.ComponentModel.DataAnnotations; +using Squidex.Infrastructure.CQRS.Commands; +using Squidex.Write.Assets.Commands; + +namespace Squidex.Controllers.Api.Assets.Models +{ + public sealed class AssetReplacedDto + { + /// + /// The mime type. + /// + [Required] + public string MimeType { get; set; } + + /// + /// The size of the file in bytes. + /// + public long FileSize { get; set; } + + /// + /// Determines of the created file is an image. + /// + public bool IsImage { get; set; } + + /// + /// The width of the image in pixels if the asset is an image. + /// + public int? PixelWidth { get; set; } + + /// + /// The height of the image in pixels if the asset is an image. + /// + public int? PixelHeight { get; set; } + + /// + /// The version of the asset. + /// + public long Version { get; set; } + + public static AssetReplacedDto Create(UpdateAsset command, EntitySavedResult result) + { + var response = new AssetReplacedDto + { + FileSize = command.File.FileSize, + MimeType = command.File.MimeType, + IsImage = command.ImageInfo != null, + PixelWidth = command.ImageInfo?.PixelWidth, + PixelHeight = command.ImageInfo?.PixelHeight, + Version = result.Version + }; + + return response; + } + } +} diff --git a/src/Squidex/Controllers/Api/Schemas/SchemaFieldsController.cs b/src/Squidex/Controllers/Api/Schemas/SchemaFieldsController.cs index 432420d00..6e9a065f9 100644 --- a/src/Squidex/Controllers/Api/Schemas/SchemaFieldsController.cs +++ b/src/Squidex/Controllers/Api/Schemas/SchemaFieldsController.cs @@ -33,7 +33,7 @@ namespace Squidex.Controllers.Api.Schemas } /// - /// Create a new schema field. + /// Add a schema field. /// /// The name of the app. /// The name of the schema. diff --git a/src/Squidex/app/features/assets/pages/asset.component.ts b/src/Squidex/app/features/assets/pages/asset.component.ts index 12005ab5b..e67a25f2e 100644 --- a/src/Squidex/app/features/assets/pages/asset.component.ts +++ b/src/Squidex/app/features/assets/pages/asset.component.ts @@ -11,9 +11,12 @@ import { ApiUrlConfig, AppComponentBase, AppsStoreService, + AssetCreatedDto, AssetDto, - AssetUpdatedDto, + AssetReplacedDto, AssetsService, + AuthService, + DateTime, fadeAnimation, MathHelper, NotificationService, @@ -77,6 +80,7 @@ export class AssetComponent extends AppComponentBase implements OnInit { constructor(apps: AppsStoreService, notifications: NotificationService, users: UsersProviderService, private readonly assetsService: AssetsService, + private readonly authService: AuthService, private readonly apiUrl: ApiUrlConfig ) { super(notifications, users, apps); @@ -89,9 +93,24 @@ export class AssetComponent extends AppComponentBase implements OnInit { this.appName() .switchMap(app => this.assetsService.uploadFile(app, initFile)) .subscribe(result => { - if (result instanceof AssetDto) { + if (result instanceof AssetCreatedDto) { setTimeout(() => { - this.asset = result; + const me = `subject:${this.authService.user!.id}`; + + const asset = new AssetDto( + this.asset.id, + me, me, + DateTime.now(), + DateTime.now(), + result.fileName, + result.fileSize, + result.mimeType, + result.isImage, + result.pixelWidth, + result.pixelHeight, + result.version); + + this.asset = asset; this.assetVersion = MathHelper.guid(); this.progress = 0; }, 2000); @@ -111,14 +130,14 @@ export class AssetComponent extends AppComponentBase implements OnInit { this.appName() .switchMap(app => this.assetsService.replaceFile(app, this.asset.id, files[0])) .subscribe(result => { - if (result instanceof AssetUpdatedDto) { + if (result instanceof AssetReplacedDto) { setTimeout(() => { + const me = `subject:${this.authService.user!.id}`; + const asset = new AssetDto( this.asset.id, - this.asset.createdBy, - result.lastModifiedBy, - this.asset.created, - result.lastModified, + this.asset.createdBy, me, + this.asset.created, DateTime.now(), this.asset.fileName, result.fileSize, result.mimeType, diff --git a/src/Squidex/app/shared/services/assets.service.ts b/src/Squidex/app/shared/services/assets.service.ts index 6950df0a9..fef1bd388 100644 --- a/src/Squidex/app/shared/services/assets.service.ts +++ b/src/Squidex/app/shared/services/assets.service.ts @@ -44,10 +44,22 @@ export class AssetDto { } } -export class AssetUpdatedDto { +export class AssetCreatedDto { + constructor( + public readonly id: string, + public readonly fileName: string, + public readonly fileSize: number, + public readonly mimeType: string, + public readonly isImage: boolean, + public readonly pixelWidth: number | null, + public readonly pixelHeight: number | null, + public readonly version: Version + ) { + } +} + +export class AssetReplacedDto { constructor( - public readonly lastModifiedBy: string, - public readonly lastModified: DateTime, public readonly fileSize: number, public readonly mimeType: string, public readonly isImage: boolean, @@ -122,8 +134,8 @@ export class AssetsService { .catchError('Failed to load assets. Please reload.'); } - public uploadFile(appName: string, file: File): Observable { - return new Observable(subscriber => { + public uploadFile(appName: string, file: File): Observable { + return new Observable(subscriber => { const url = this.apiUrl.buildUrl(`api/apps/${appName}/assets/`); const content = new FormData(); @@ -137,12 +149,8 @@ export class AssetsService { .post(url, content, { headers }) .map(response => response.json()) .map(response => { - return new AssetDto( + return new AssetCreatedDto( response.id, - response.createdBy, - response.lastModifiedBy, - DateTime.parseISO_UTC(response.created), - DateTime.parseISO_UTC(response.lastModified), response.fileName, response.fileSize, response.mimeType, @@ -162,8 +170,8 @@ export class AssetsService { }); } - public replaceFile(appName: string, id: string, file: File): Observable { - return new Observable(subscriber => { + public replaceFile(appName: string, id: string, file: File): Observable { + return new Observable(subscriber => { const url = this.apiUrl.buildUrl(`api/apps/${appName}/assets/${id}/content`); const content = new FormData(); @@ -177,9 +185,7 @@ export class AssetsService { .put(url, content, { headers }) .map(response => response.json()) .map(response => { - return new AssetUpdatedDto( - response.lastModifiedBy, - DateTime.parseISO_UTC(response.lastModified), + return new AssetReplacedDto( response.fileSize, response.mimeType, response.isImage,