diff --git a/backend/src/Socialize.Api/Migrations/20260505192305_Initial.Designer.cs b/backend/src/Socialize.Api/Migrations/20260505204545_Initial.Designer.cs similarity index 98% rename from backend/src/Socialize.Api/Migrations/20260505192305_Initial.Designer.cs rename to backend/src/Socialize.Api/Migrations/20260505204545_Initial.Designer.cs index 7134872..034e125 100644 --- a/backend/src/Socialize.Api/Migrations/20260505192305_Initial.Designer.cs +++ b/backend/src/Socialize.Api/Migrations/20260505204545_Initial.Designer.cs @@ -12,7 +12,7 @@ using Socialize.Api.Data; namespace Socialize.Api.Migrations { [DbContext(typeof(AppDbContext))] - [Migration("20260505192305_Initial")] + [Migration("20260505204545_Initial")] partial class Initial { /// @@ -912,6 +912,29 @@ namespace Socialize.Api.Migrations .ValueGeneratedOnAdd() .HasColumnType("uuid"); + b.Property("AttachmentBlobContainerName") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("AttachmentBlobName") + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("AttachmentBlobUrl") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("AttachmentContentType") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("AttachmentFileName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("AttachmentSizeBytes") + .HasColumnType("bigint"); + b.Property("AuthorDisplayName") .IsRequired() .HasMaxLength(256) diff --git a/backend/src/Socialize.Api/Migrations/20260505192305_Initial.cs b/backend/src/Socialize.Api/Migrations/20260505204545_Initial.cs similarity index 98% rename from backend/src/Socialize.Api/Migrations/20260505192305_Initial.cs rename to backend/src/Socialize.Api/Migrations/20260505204545_Initial.cs index 790ae48..7ae8ba5 100644 --- a/backend/src/Socialize.Api/Migrations/20260505192305_Initial.cs +++ b/backend/src/Socialize.Api/Migrations/20260505204545_Initial.cs @@ -282,6 +282,12 @@ namespace Socialize.Api.Migrations AuthorDisplayName = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), AuthorEmail = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), Body = table.Column(type: "character varying(4000)", maxLength: 4000, nullable: false), + AttachmentFileName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + AttachmentContentType = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + AttachmentSizeBytes = table.Column(type: "bigint", nullable: true), + AttachmentBlobContainerName = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + AttachmentBlobName = table.Column(type: "character varying(512)", maxLength: 512, nullable: true), + AttachmentBlobUrl = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true), CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "CURRENT_TIMESTAMP") }, constraints: table => diff --git a/backend/src/Socialize.Api/Migrations/AppDbContextModelSnapshot.cs b/backend/src/Socialize.Api/Migrations/AppDbContextModelSnapshot.cs index 22b5e91..c0d4088 100644 --- a/backend/src/Socialize.Api/Migrations/AppDbContextModelSnapshot.cs +++ b/backend/src/Socialize.Api/Migrations/AppDbContextModelSnapshot.cs @@ -909,6 +909,29 @@ namespace Socialize.Api.Migrations .ValueGeneratedOnAdd() .HasColumnType("uuid"); + b.Property("AttachmentBlobContainerName") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("AttachmentBlobName") + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("AttachmentBlobUrl") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("AttachmentContentType") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("AttachmentFileName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("AttachmentSizeBytes") + .HasColumnType("bigint"); + b.Property("AuthorDisplayName") .IsRequired() .HasMaxLength(256) diff --git a/backend/src/Socialize.Api/Modules/Comments/Data/Comment.cs b/backend/src/Socialize.Api/Modules/Comments/Data/Comment.cs index 2ab05a8..0e0c67a 100644 --- a/backend/src/Socialize.Api/Modules/Comments/Data/Comment.cs +++ b/backend/src/Socialize.Api/Modules/Comments/Data/Comment.cs @@ -10,5 +10,11 @@ public class Comment public required string AuthorDisplayName { get; set; } public required string AuthorEmail { get; set; } public required string Body { get; set; } + public string? AttachmentFileName { get; set; } + public string? AttachmentContentType { get; set; } + public long? AttachmentSizeBytes { get; set; } + public string? AttachmentBlobContainerName { get; set; } + public string? AttachmentBlobName { get; set; } + public string? AttachmentBlobUrl { get; set; } public DateTimeOffset CreatedAt { get; init; } } diff --git a/backend/src/Socialize.Api/Modules/Comments/Data/CommentModelConfiguration.cs b/backend/src/Socialize.Api/Modules/Comments/Data/CommentModelConfiguration.cs index 973e6ae..e9409af 100644 --- a/backend/src/Socialize.Api/Modules/Comments/Data/CommentModelConfiguration.cs +++ b/backend/src/Socialize.Api/Modules/Comments/Data/CommentModelConfiguration.cs @@ -13,6 +13,11 @@ public static class CommentModelConfiguration comment.Property(x => x.AuthorDisplayName).HasMaxLength(256).IsRequired(); comment.Property(x => x.AuthorEmail).HasMaxLength(256).IsRequired(); comment.Property(x => x.Body).HasMaxLength(4000).IsRequired(); + comment.Property(x => x.AttachmentFileName).HasMaxLength(256); + comment.Property(x => x.AttachmentContentType).HasMaxLength(128); + comment.Property(x => x.AttachmentBlobContainerName).HasMaxLength(128); + comment.Property(x => x.AttachmentBlobName).HasMaxLength(512); + comment.Property(x => x.AttachmentBlobUrl).HasMaxLength(1024); comment.Property(x => x.CreatedAt) .ValueGeneratedOnAdd() .HasDefaultValueSql("CURRENT_TIMESTAMP"); diff --git a/backend/src/Socialize.Api/Modules/Comments/Handlers/CreateComment.cs b/backend/src/Socialize.Api/Modules/Comments/Handlers/CreateComment.cs index 330d97a..881e7d4 100644 --- a/backend/src/Socialize.Api/Modules/Comments/Handlers/CreateComment.cs +++ b/backend/src/Socialize.Api/Modules/Comments/Handlers/CreateComment.cs @@ -1,6 +1,7 @@ using FastEndpoints; using Microsoft.EntityFrameworkCore; using Socialize.Api.Data; +using Socialize.Api.Infrastructure.BlobStorage.Contracts; using Socialize.Api.Infrastructure.Security; using Socialize.Api.Modules.ContentItems.Contracts; using Socialize.Api.Modules.ContentItems.Data; @@ -14,7 +15,8 @@ public record CreateCommentRequest( Guid WorkspaceId, Guid ContentItemId, Guid? ParentCommentId, - string Body); + string Body, + IFormFile? Attachment); public class CreateCommentRequestValidator : Validator @@ -23,13 +25,14 @@ public class CreateCommentRequestValidator { RuleFor(x => x.WorkspaceId).NotEmpty(); RuleFor(x => x.ContentItemId).NotEmpty(); - RuleFor(x => x.Body).NotEmpty().MaximumLength(4000); + RuleFor(x => x.Body).MaximumLength(4000); } } public class CreateCommentHandler( AppDbContext dbContext, AccessScopeService accessScopeService, + IBlobStorage blobStorage, IContentItemActivityWriter activityWriter, INotificationEventWriter notificationEventWriter) : Endpoint @@ -38,10 +41,19 @@ public class CreateCommentHandler( { Post("/api/comments"); Options(o => o.WithTags("Comments")); + AllowFileUploads(); } public override async Task HandleAsync(CreateCommentRequest request, CancellationToken ct) { + string body = request.Body?.Trim() ?? string.Empty; + if (string.IsNullOrWhiteSpace(body) && request.Attachment is null) + { + AddError(request => request.Body, "A comment body or attachment is required."); + await SendErrorsAsync(StatusCodes.Status400BadRequest, ct); + return; + } + ContentItem? contentItem = await dbContext.ContentItems .SingleOrDefaultAsync( candidate => candidate.Id == request.ContentItemId && candidate.WorkspaceId == request.WorkspaceId, @@ -75,16 +87,70 @@ public class CreateCommentHandler( } } + Guid commentId = Guid.NewGuid(); + string? attachmentFileName = null; + string? attachmentContentType = null; + long? attachmentSizeBytes = null; + string? attachmentBlobName = null; + string? attachmentBlobUrl = null; + + if (request.Attachment is not null) + { + string normalizedContentType = request.Attachment.ContentType.Trim().ToLowerInvariant(); + + if (request.Attachment.Length <= 0) + { + AddError(request => request.Attachment, "The attachment must not be empty."); + await SendErrorsAsync(StatusCodes.Status400BadRequest, ct); + return; + } + + if (!IsInlineAttachmentContentType(normalizedContentType)) + { + AddError(request => request.Attachment, "The attachment must be a PNG or JPEG image."); + await SendErrorsAsync(StatusCodes.Status400BadRequest, ct); + return; + } + + attachmentFileName = NormalizeFileName(request.Attachment.FileName, normalizedContentType); + attachmentContentType = normalizedContentType; + attachmentSizeBytes = request.Attachment.Length; + attachmentBlobName = + $"{contentItem.WorkspaceId}/{SubDirectoryNames.Contents}/{contentItem.Id}/comments/{commentId}/{attachmentFileName}"; + + try + { + attachmentBlobUrl = await blobStorage.UploadFileAsync( + ContainerNames.Workspaces, + attachmentBlobName, + request.Attachment.OpenReadStream(), + normalizedContentType, + ct); + } + catch (InvalidOperationException) + { + AddError(request => request.Attachment, "The attachment file is invalid or unsupported."); + await SendErrorsAsync(StatusCodes.Status400BadRequest, ct); + return; + } + } + Comment comment = new() { - Id = Guid.NewGuid(), + Id = commentId, WorkspaceId = request.WorkspaceId, ContentItemId = request.ContentItemId, ParentCommentId = request.ParentCommentId, AuthorUserId = User.GetUserId(), AuthorDisplayName = User.GetAlias() ?? User.GetName(), AuthorEmail = User.GetEmail(), - Body = request.Body.Trim(), + Body = body, + AttachmentFileName = attachmentFileName, + AttachmentContentType = attachmentContentType, + AttachmentSizeBytes = attachmentSizeBytes, + AttachmentBlobContainerName = attachmentBlobName is not null ? ContainerNames.Workspaces : null, + AttachmentBlobName = attachmentBlobName, + AttachmentBlobUrl = attachmentBlobUrl, CreatedAt = DateTimeOffset.UtcNow, }; @@ -109,6 +175,7 @@ public class CreateCommentHandler( JsonSerializer.Serialize(new { parentCommentId = comment.ParentCommentId, + attachmentFileName = comment.AttachmentFileName, })), ct); @@ -135,8 +202,34 @@ public class CreateCommentHandler( comment.AuthorEmail, authorPortraitUrl, comment.Body, + comment.AttachmentFileName, + comment.AttachmentContentType, + comment.AttachmentSizeBytes, + comment.AttachmentBlobUrl, comment.CreatedAt); await SendAsync(dto, StatusCodes.Status201Created, ct); } + + private static bool IsInlineAttachmentContentType(string contentType) + { + return contentType.Trim().ToLowerInvariant() is "image/png" or "image/jpeg" or "image/jpg"; + } + + private static string NormalizeFileName(string? fileName, string contentType) + { + string extension = contentType.Trim().ToLowerInvariant() switch + { + "image/png" => ".png", + "image/jpeg" or "image/jpg" => ".jpg", + _ => string.Empty, + }; + string normalized = Path.GetFileName(fileName ?? string.Empty).Trim(); + if (string.IsNullOrWhiteSpace(normalized)) + { + return $"comment-attachment{extension}"; + } + + return normalized.Length > 256 ? normalized[..256] : normalized; + } } diff --git a/backend/src/Socialize.Api/Modules/Comments/Handlers/GetComments.cs b/backend/src/Socialize.Api/Modules/Comments/Handlers/GetComments.cs index 8da12e1..cd33e4f 100644 --- a/backend/src/Socialize.Api/Modules/Comments/Handlers/GetComments.cs +++ b/backend/src/Socialize.Api/Modules/Comments/Handlers/GetComments.cs @@ -19,6 +19,10 @@ public record CommentDto( string AuthorEmail, string? AuthorPortraitUrl, string Body, + string? AttachmentFileName, + string? AttachmentContentType, + long? AttachmentSizeBytes, + string? AttachmentBlobUrl, DateTimeOffset CreatedAt); public class GetCommentsHandler( @@ -73,6 +77,10 @@ public class GetCommentsHandler( comment.AuthorEmail, authorPortraits.GetValueOrDefault(comment.AuthorUserId), comment.Body, + comment.AttachmentFileName, + comment.AttachmentContentType, + comment.AttachmentSizeBytes, + comment.AttachmentBlobUrl, comment.CreatedAt)) .ToList(); diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.Build.Locator.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.Build.Locator.dll" deleted file mode 100755 index 13b1021..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.Build.Locator.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe" deleted file mode 100755 index 00dd99f..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe.config" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe.config" deleted file mode 100755 index 14c9184..0000000 --- "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe.config" +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.IO.Redist.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.IO.Redist.dll" deleted file mode 100755 index 88e63d8..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Microsoft.IO.Redist.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Newtonsoft.Json.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Newtonsoft.Json.dll" deleted file mode 100755 index 1d035d6..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/Newtonsoft.Json.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Buffers.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Buffers.dll" deleted file mode 100755 index f2d83c5..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Buffers.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Collections.Immutable.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Collections.Immutable.dll" deleted file mode 100755 index 7594b2e..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Collections.Immutable.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.CommandLine.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.CommandLine.dll" deleted file mode 100755 index d0bbad5..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.CommandLine.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Memory.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Memory.dll" deleted file mode 100755 index 4617199..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Memory.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Numerics.Vectors.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Numerics.Vectors.dll" deleted file mode 100755 index 0865972..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Numerics.Vectors.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Runtime.CompilerServices.Unsafe.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Runtime.CompilerServices.Unsafe.dll" deleted file mode 100755 index c5ba4e4..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Runtime.CompilerServices.Unsafe.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Threading.Tasks.Extensions.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Threading.Tasks.Extensions.dll" deleted file mode 100755 index eeec928..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/System.Threading.Tasks.Extensions.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/cs/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/cs/System.CommandLine.resources.dll" deleted file mode 100755 index 0be3757..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/cs/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/de/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/de/System.CommandLine.resources.dll" deleted file mode 100755 index bfed293..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/de/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/es/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/es/System.CommandLine.resources.dll" deleted file mode 100755 index 5e1c416..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/es/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/fr/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/fr/System.CommandLine.resources.dll" deleted file mode 100755 index 2916bdf..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/fr/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/it/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/it/System.CommandLine.resources.dll" deleted file mode 100755 index 1a55c94..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/it/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/ja/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/ja/System.CommandLine.resources.dll" deleted file mode 100755 index c1be153..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/ja/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/ko/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/ko/System.CommandLine.resources.dll" deleted file mode 100755 index bfcbbc6..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/ko/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/pl/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/pl/System.CommandLine.resources.dll" deleted file mode 100755 index b9efaec..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/pl/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/pt-BR/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/pt-BR/System.CommandLine.resources.dll" deleted file mode 100755 index 69612cb..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/pt-BR/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/ru/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/ru/System.CommandLine.resources.dll" deleted file mode 100755 index 042aaf8..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/ru/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/tr/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/tr/System.CommandLine.resources.dll" deleted file mode 100755 index 629b98b..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/tr/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/zh-Hans/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/zh-Hans/System.CommandLine.resources.dll" deleted file mode 100755 index ff8dacb..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/zh-Hans/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/zh-Hant/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/zh-Hant/System.CommandLine.resources.dll" deleted file mode 100755 index 9b9870a..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-net472/zh-Hant/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.Build.Locator.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.Build.Locator.dll" deleted file mode 100755 index cafcf21..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.Build.Locator.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.deps.json" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.deps.json" deleted file mode 100755 index 059c550..0000000 --- "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.deps.json" +++ /dev/null @@ -1,260 +0,0 @@ -{ - "runtimeTarget": { - "name": ".NETCoreApp,Version=v6.0", - "signature": "" - }, - "compilationOptions": {}, - "targets": { - ".NETCoreApp,Version=v6.0": { - "Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost/4.14.0-3.25262.10": { - "dependencies": { - "Microsoft.Build.Locator": "1.6.10", - "Microsoft.CodeAnalysis.NetAnalyzers": "8.0.0-preview.23468.1", - "Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers": "3.3.4-beta1.22504.1", - "Microsoft.DotNet.XliffTasks": "9.0.0-beta.25255.5", - "Microsoft.VisualStudio.Threading.Analyzers": "17.13.2", - "Newtonsoft.Json": "13.0.3", - "Roslyn.Diagnostics.Analyzers": "3.11.0-beta1.24081.1", - "System.Collections.Immutable": "9.0.0", - "System.CommandLine": "2.0.0-beta4.24528.1" - }, - "runtime": { - "Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll": {} - }, - "resources": { - "cs/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "cs" - }, - "de/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "de" - }, - "es/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "es" - }, - "fr/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "fr" - }, - "it/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "it" - }, - "ja/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "ja" - }, - "ko/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "ko" - }, - "pl/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "pl" - }, - "pt-BR/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "pt-BR" - }, - "ru/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "ru" - }, - "tr/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "tr" - }, - "zh-Hans/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "zh-Hans" - }, - "zh-Hant/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll": { - "locale": "zh-Hant" - } - } - }, - "Microsoft.Build.Locator/1.6.10": { - "runtime": { - "lib/net6.0/Microsoft.Build.Locator.dll": { - "assemblyVersion": "1.0.0.0", - "fileVersion": "1.6.10.57384" - } - } - }, - "Microsoft.CodeAnalysis.BannedApiAnalyzers/3.11.0-beta1.24081.1": {}, - "Microsoft.CodeAnalysis.NetAnalyzers/8.0.0-preview.23468.1": {}, - "Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers/3.3.4-beta1.22504.1": {}, - "Microsoft.CodeAnalysis.PublicApiAnalyzers/3.11.0-beta1.24081.1": {}, - "Microsoft.DotNet.XliffTasks/9.0.0-beta.25255.5": {}, - "Microsoft.VisualStudio.Threading.Analyzers/17.13.2": {}, - "Newtonsoft.Json/13.0.3": { - "runtime": { - "lib/net6.0/Newtonsoft.Json.dll": { - "assemblyVersion": "13.0.0.0", - "fileVersion": "13.0.3.27908" - } - } - }, - "Roslyn.Diagnostics.Analyzers/3.11.0-beta1.24081.1": { - "dependencies": { - "Microsoft.CodeAnalysis.BannedApiAnalyzers": "3.11.0-beta1.24081.1", - "Microsoft.CodeAnalysis.PublicApiAnalyzers": "3.11.0-beta1.24081.1" - } - }, - "System.Collections.Immutable/9.0.0": { - "dependencies": { - "System.Memory": "4.5.5", - "System.Runtime.CompilerServices.Unsafe": "6.0.0" - }, - "runtime": { - "lib/netstandard2.0/System.Collections.Immutable.dll": { - "assemblyVersion": "9.0.0.0", - "fileVersion": "9.0.24.52809" - } - } - }, - "System.CommandLine/2.0.0-beta4.24528.1": { - "dependencies": { - "System.Memory": "4.5.5" - }, - "runtime": { - "lib/netstandard2.0/System.CommandLine.dll": { - "assemblyVersion": "2.0.0.0", - "fileVersion": "2.0.24.52801" - } - }, - "resources": { - "lib/netstandard2.0/cs/System.CommandLine.resources.dll": { - "locale": "cs" - }, - "lib/netstandard2.0/de/System.CommandLine.resources.dll": { - "locale": "de" - }, - "lib/netstandard2.0/es/System.CommandLine.resources.dll": { - "locale": "es" - }, - "lib/netstandard2.0/fr/System.CommandLine.resources.dll": { - "locale": "fr" - }, - "lib/netstandard2.0/it/System.CommandLine.resources.dll": { - "locale": "it" - }, - "lib/netstandard2.0/ja/System.CommandLine.resources.dll": { - "locale": "ja" - }, - "lib/netstandard2.0/ko/System.CommandLine.resources.dll": { - "locale": "ko" - }, - "lib/netstandard2.0/pl/System.CommandLine.resources.dll": { - "locale": "pl" - }, - "lib/netstandard2.0/pt-BR/System.CommandLine.resources.dll": { - "locale": "pt-BR" - }, - "lib/netstandard2.0/ru/System.CommandLine.resources.dll": { - "locale": "ru" - }, - "lib/netstandard2.0/tr/System.CommandLine.resources.dll": { - "locale": "tr" - }, - "lib/netstandard2.0/zh-Hans/System.CommandLine.resources.dll": { - "locale": "zh-Hans" - }, - "lib/netstandard2.0/zh-Hant/System.CommandLine.resources.dll": { - "locale": "zh-Hant" - } - } - }, - "System.Memory/4.5.5": {}, - "System.Runtime.CompilerServices.Unsafe/6.0.0": {} - } - }, - "libraries": { - "Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost/4.14.0-3.25262.10": { - "type": "project", - "serviceable": false, - "sha512": "" - }, - "Microsoft.Build.Locator/1.6.10": { - "type": "package", - "serviceable": true, - "sha512": "sha512-DJhCkTGqy1LMJzEmG/2qxRTMHwdPc3WdVoGQI5o5mKHVo4dsHrCMLIyruwU/NSvPNSdvONlaf7jdFXnAMuxAuA==", - "path": "microsoft.build.locator/1.6.10", - "hashPath": "microsoft.build.locator.1.6.10.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.BannedApiAnalyzers/3.11.0-beta1.24081.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-DH6L3rsbjppLrHM2l2/NKbnMaYd0NFHx2pjZaFdrVcRkONrV3i9FHv6Id8Dp6/TmjhXQsJVJJFbhhjkpuP1xxg==", - "path": "microsoft.codeanalysis.bannedapianalyzers/3.11.0-beta1.24081.1", - "hashPath": "microsoft.codeanalysis.bannedapianalyzers.3.11.0-beta1.24081.1.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.NetAnalyzers/8.0.0-preview.23468.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ZhIvyxmUCqb8OiU/VQfxfuAmIB4lQsjqhMVYKeoyxzSI+d7uR5Pzx3ZKoaIhPizQ15wa4lnyD6wg3TnSJ6P4LA==", - "path": "microsoft.codeanalysis.netanalyzers/8.0.0-preview.23468.1", - "hashPath": "microsoft.codeanalysis.netanalyzers.8.0.0-preview.23468.1.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers/3.3.4-beta1.22504.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-2XRlqPAzVke7Sb80+UqaC7o57OwfK+tIr+aIOxrx41RWDMeR2SBUW7kL4sd6hfLFfBNsLo3W5PT+UwfvwPaOzA==", - "path": "microsoft.codeanalysis.performancesensitiveanalyzers/3.3.4-beta1.22504.1", - "hashPath": "microsoft.codeanalysis.performancesensitiveanalyzers.3.3.4-beta1.22504.1.nupkg.sha512" - }, - "Microsoft.CodeAnalysis.PublicApiAnalyzers/3.11.0-beta1.24081.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-3bYGBihvoNO0rhCOG1U9O50/4Q8suZ+glHqQLIAcKvnodSnSW+dYWYzTNb1UbS8pUS8nAUfxSFMwuMup/G5DtQ==", - "path": "microsoft.codeanalysis.publicapianalyzers/3.11.0-beta1.24081.1", - "hashPath": "microsoft.codeanalysis.publicapianalyzers.3.11.0-beta1.24081.1.nupkg.sha512" - }, - "Microsoft.DotNet.XliffTasks/9.0.0-beta.25255.5": { - "type": "package", - "serviceable": true, - "sha512": "sha512-bb0fZB5ViPscdfYeWlmtyXJMzNkgcpkV5RWmXktfV9lwIUZgNZmFotUXrdcTyZzrN7v1tQK/Y6BGnbkP9gEsXg==", - "path": "microsoft.dotnet.xlifftasks/9.0.0-beta.25255.5", - "hashPath": "microsoft.dotnet.xlifftasks.9.0.0-beta.25255.5.nupkg.sha512" - }, - "Microsoft.VisualStudio.Threading.Analyzers/17.13.2": { - "type": "package", - "serviceable": true, - "sha512": "sha512-Qcd8IlaTXZVq3wolBnzby1P7kWihdWaExtD8riumiKuG1sHa8EgjV/o70TMjTaeUMhomBbhfdC9OPwAHoZfnjQ==", - "path": "microsoft.visualstudio.threading.analyzers/17.13.2", - "hashPath": "microsoft.visualstudio.threading.analyzers.17.13.2.nupkg.sha512" - }, - "Newtonsoft.Json/13.0.3": { - "type": "package", - "serviceable": true, - "sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", - "path": "newtonsoft.json/13.0.3", - "hashPath": "newtonsoft.json.13.0.3.nupkg.sha512" - }, - "Roslyn.Diagnostics.Analyzers/3.11.0-beta1.24081.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-reHqZCDKifA+DURcL8jUfYkMGL4FpgNt5LI0uWTS6IpM8kKVbu/kO8byZsqfhBu4wUzT3MBDcoMfzhZPdENIpg==", - "path": "roslyn.diagnostics.analyzers/3.11.0-beta1.24081.1", - "hashPath": "roslyn.diagnostics.analyzers.3.11.0-beta1.24081.1.nupkg.sha512" - }, - "System.Collections.Immutable/9.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w==", - "path": "system.collections.immutable/9.0.0", - "hashPath": "system.collections.immutable.9.0.0.nupkg.sha512" - }, - "System.CommandLine/2.0.0-beta4.24528.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-Xt8tsSU8yd0ZpbT9gl5DAwkMYWLo8PV1fq2R/belrUbHVVOIKqhLfbWksbdknUDpmzMHZenBtD6AGAp9uJTa2w==", - "path": "system.commandline/2.0.0-beta4.24528.1", - "hashPath": "system.commandline.2.0.0-beta4.24528.1.nupkg.sha512" - }, - "System.Memory/4.5.5": { - "type": "package", - "serviceable": true, - "sha512": "sha512-XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", - "path": "system.memory/4.5.5", - "hashPath": "system.memory.4.5.5.nupkg.sha512" - }, - "System.Runtime.CompilerServices.Unsafe/6.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==", - "path": "system.runtime.compilerservices.unsafe/6.0.0", - "hashPath": "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512" - } - } -} \ No newline at end of file diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll" deleted file mode 100755 index 993b54f..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll.config" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll.config" deleted file mode 100755 index f78385c..0000000 --- "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll.config" +++ /dev/null @@ -1,659 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.runtimeconfig.json" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.runtimeconfig.json" deleted file mode 100755 index 9a67d63..0000000 --- "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.runtimeconfig.json" +++ /dev/null @@ -1,13 +0,0 @@ -{ - "runtimeOptions": { - "tfm": "net6.0", - "framework": { - "name": "Microsoft.NETCore.App", - "version": "6.0.0" - }, - "rollForward": "Major", - "configProperties": { - "System.Reflection.Metadata.MetadataUpdater.IsSupported": false - } - } -} \ No newline at end of file diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Newtonsoft.Json.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Newtonsoft.Json.dll" deleted file mode 100755 index 87bf9aa..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/Newtonsoft.Json.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/System.Collections.Immutable.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/System.Collections.Immutable.dll" deleted file mode 100755 index b182127..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/System.Collections.Immutable.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/System.CommandLine.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/System.CommandLine.dll" deleted file mode 100755 index d0bbad5..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/System.CommandLine.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/cs/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/cs/System.CommandLine.resources.dll" deleted file mode 100755 index 0be3757..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/cs/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/de/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/de/System.CommandLine.resources.dll" deleted file mode 100755 index bfed293..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/de/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/es/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/es/System.CommandLine.resources.dll" deleted file mode 100755 index 5e1c416..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/es/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/fr/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/fr/System.CommandLine.resources.dll" deleted file mode 100755 index 2916bdf..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/fr/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/it/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/it/System.CommandLine.resources.dll" deleted file mode 100755 index 1a55c94..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/it/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/ja/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/ja/System.CommandLine.resources.dll" deleted file mode 100755 index c1be153..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/ja/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/ko/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/ko/System.CommandLine.resources.dll" deleted file mode 100755 index bfcbbc6..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/ko/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/pl/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/pl/System.CommandLine.resources.dll" deleted file mode 100755 index b9efaec..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/pl/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/pt-BR/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/pt-BR/System.CommandLine.resources.dll" deleted file mode 100755 index 69612cb..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/pt-BR/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/ru/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/ru/System.CommandLine.resources.dll" deleted file mode 100755 index 042aaf8..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/ru/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/tr/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/tr/System.CommandLine.resources.dll" deleted file mode 100755 index 629b98b..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/tr/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/zh-Hans/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/zh-Hans/System.CommandLine.resources.dll" deleted file mode 100755 index ff8dacb..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/zh-Hans/System.CommandLine.resources.dll" and /dev/null differ diff --git "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/zh-Hant/System.CommandLine.resources.dll" "b/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/zh-Hant/System.CommandLine.resources.dll" deleted file mode 100755 index 9b9870a..0000000 Binary files "a/backend/src/Socialize.Api/bin\\Debug/net10.0/BuildHost-netcore/zh-Hant/System.CommandLine.resources.dll" and /dev/null differ diff --git a/docs/TASKS/content/007-content-comment-composer-toolbar.md b/docs/TASKS/content/007-content-comment-composer-toolbar.md new file mode 100644 index 0000000..798f49e --- /dev/null +++ b/docs/TASKS/content/007-content-comment-composer-toolbar.md @@ -0,0 +1,34 @@ +# Task: Polish content detail comment composer + +## Goal + +Make the content detail production comments composer feel like a collaboration input instead of a detached form. + +## Scope + +- Show the current user's avatar inside the comment composer. +- Put the comment textarea to the right of the avatar. +- Move the post action into the composer bottom row. +- Add bottom-row controls for internal comment intent, media references, and member mentions. +- Upload comment attachments from the user's computer to workspace blob storage. +- Show uploaded comment attachments inline in the comment thread. +- Add the minimal comments API contract and persistence needed for inline attachments. + +## Relevant Files + +- `frontend/src/features/content/views/ContentItemDetailView.vue` +- `frontend/src/features/content/components/ContentCommentComposer.vue` +- `frontend/src/features/content/components/ContentCommentFeed.vue` +- `frontend/src/features/content/stores/contentItemDetailStore.js` +- `backend/src/Socialize.Api/Modules/Comments/` +- `shared/openapi/openapi.json` + +## Validation + +```bash +cd frontend +npm run build +cd .. +dotnet build backend/src/Socialize.Api/Socialize.Api.csproj -v minimal +dotnet test backend/tests/Socialize.Tests/Socialize.Tests.csproj --no-build -v minimal +``` diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 2e67e1a..e76bc0c 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,6 +1,9 @@ FROM node:22-alpine AS build WORKDIR /app +ARG VITE_API_URL=/api +ENV VITE_API_URL=$VITE_API_URL + COPY frontend/package*.json ./ RUN npm ci diff --git a/frontend/src/api/schema.d.ts b/frontend/src/api/schema.d.ts index c0d2c40..35f25f6 100644 --- a/frontend/src/api/schema.d.ts +++ b/frontend/src/api/schema.d.ts @@ -116,6 +116,22 @@ export interface paths { patch?: never; trace?: never; }; + "/api/organizations/{organizationId}/logo": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: operations["SocializeApiModulesOrganizationsHandlersChangeOrganizationLogoHandler"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/organizations/{organizationId}": { parameters: { query?: never; @@ -708,6 +724,22 @@ export interface paths { patch?: never; trace?: never; }; + "/api/content-items/{id}/activity": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: operations["SocializeApiModulesContentItemsHandlersGetContentItemActivityHandler"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/content-items/{id}/status": { parameters: { query?: never; @@ -740,22 +772,6 @@ export interface paths { patch?: never; trace?: never; }; - "/api/comments/{id}/resolve": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post: operations["SocializeApiModulesCommentsHandlersResolveCommentHandler"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; "/api/clients/{id}/portrait": { parameters: { query?: never; @@ -868,6 +884,118 @@ export interface paths { patch?: never; trace?: never; }; + "/api/calendar-integrations/catalog": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: operations["SocializeApiModulesCalendarIntegrationsHandlersListCalendarCatalogHandler"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/calendar-integrations/events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: operations["SocializeApiModulesCalendarIntegrationsHandlersListCalendarEventsHandler"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/calendar-integrations/sources/{sourceId}/refresh": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: operations["SocializeApiModulesCalendarIntegrationsHandlersRefreshCalendarSourceHandler"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/calendar-integrations/export-feed": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: operations["SocializeApiModulesCalendarIntegrationsHandlersGetUserCalendarExportFeedHandler"]; + put?: never; + post?: never; + delete: operations["SocializeApiModulesCalendarIntegrationsHandlersRevokeUserCalendarExportFeedHandler"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/calendar-integrations/export-feed/enable": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: operations["SocializeApiModulesCalendarIntegrationsHandlersEnableUserCalendarExportFeedHandler"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/calendar-integrations/export-feed/regenerate": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: operations["SocializeApiModulesCalendarIntegrationsHandlersRegenerateUserCalendarExportFeedHandler"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/calendar-integrations/export-feed/{token}.ics": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: operations["SocializeApiModulesCalendarIntegrationsHandlersGetUserCalendarExportFeedIcsHandler"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/assets/{id}/revisions": { parameters: { query?: never; @@ -1067,18 +1195,38 @@ export interface components { email: string; role: string; }; + SocializeApiModulesOrganizationsHandlersChangeOrganizationLogoResponse: { + blobUrl?: string; + }; + SocializeApiModulesOrganizationsHandlersChangeOrganizationLogoRequest: { + /** Format: binary */ + file: string; + }; SocializeApiModulesOrganizationsHandlersOrganizationDto: { /** Format: guid */ id?: string; name?: string; + logoUrl?: string | null; /** Format: guid */ ownerUserId?: string; currentUserPermissions?: string[]; members?: components["schemas"]["SocializeApiModulesOrganizationsHandlersOrganizationMemberDto"][]; workspaces?: components["schemas"]["SocializeApiModulesWorkspacesHandlersWorkspaceDto"][]; + usage?: components["schemas"]["SocializeApiModulesOrganizationsHandlersOrganizationUsageDto"] | null; /** Format: date-time */ createdAt?: string; }; + SocializeApiModulesOrganizationsHandlersOrganizationUsageDto: { + planName?: string; + items?: components["schemas"]["SocializeApiModulesOrganizationsHandlersOrganizationUsageItemDto"][]; + }; + SocializeApiModulesOrganizationsHandlersOrganizationUsageItemDto: { + key?: string; + /** Format: int32 */ + used?: number; + /** Format: int32 */ + limit?: number | null; + }; SocializeApiModulesOrganizationsHandlersUpdateOrganizationRequest: { name: string; }; @@ -1386,6 +1534,8 @@ export interface components { publicationTargets: string; hashtags?: string | null; changeSummary?: string | null; + /** Format: date-time */ + dueDate?: string | null; }; SocializeApiModulesContentItemsHandlersContentItemDetailDto: { /** Format: guid */ @@ -1409,6 +1559,25 @@ export interface components { /** Format: date-time */ createdAt?: string; }; + SocializeApiModulesContentItemsHandlersContentItemActivityEntryDto: { + /** Format: guid */ + id?: string; + /** Format: guid */ + workspaceId?: string; + /** Format: guid */ + contentItemId?: string; + eventType?: string; + entityType?: string; + /** Format: guid */ + entityId?: string; + summary?: string; + /** Format: guid */ + actorUserId?: string | null; + actorEmail?: string | null; + metadataJson?: string | null; + /** Format: date-time */ + createdAt?: string; + }; SocializeApiModulesContentItemsHandlersGetContentItemsRequest: Record; SocializeApiModulesContentItemsHandlersUpdateContentItemStatusRequest: { status: string; @@ -1428,11 +1597,13 @@ export interface components { authorEmail?: string; authorPortraitUrl?: string | null; body?: string; - isResolved?: boolean; + attachmentFileName?: string | null; + attachmentContentType?: string | null; + /** Format: int64 */ + attachmentSizeBytes?: number | null; + attachmentBlobUrl?: string | null; /** Format: date-time */ createdAt?: string; - /** Format: date-time */ - resolvedAt?: string | null; }; SocializeApiModulesCommentsHandlersCreateCommentRequest: { /** Format: guid */ @@ -1441,7 +1612,9 @@ export interface components { contentItemId: string; /** Format: guid */ parentCommentId?: string | null; - body: string; + body?: string; + /** Format: binary */ + attachment?: string | null; }; SocializeApiModulesCommentsHandlersGetCommentsRequest: Record; SocializeApiModulesClientsHandlersChangeClientPortraitResponse: { @@ -1576,7 +1749,65 @@ export interface components { isEnabled?: boolean; inheritanceMode?: string | null; }; + SocializeApiModulesCalendarIntegrationsHandlersCalendarCatalogEntryDto: { + /** Format: guid */ + id?: string; + title?: string; + description?: string; + country?: string | null; + region?: string | null; + language?: string; + category?: string; + cultureOrReligion?: string | null; + providerName?: string; + sourceUrl?: string; + trustLevel?: string; + defaultColor?: string; + }; + SocializeApiModulesCalendarIntegrationsHandlersListCalendarCatalogRequest: Record; + SocializeApiModulesCalendarIntegrationsHandlersCalendarEventDto: { + /** Format: guid */ + id?: string; + /** Format: guid */ + calendarSourceId?: string; + sourceEventUid?: string; + title?: string; + description?: string | null; + isAllDay?: boolean; + isFloatingTime?: boolean; + /** Format: date */ + startDate?: string; + /** Format: date */ + endDate?: string; + /** Format: date-time */ + startLocalDateTime?: string | null; + /** Format: date-time */ + endLocalDateTime?: string | null; + /** Format: date-time */ + startUtc?: string | null; + /** Format: date-time */ + endUtc?: string | null; + timeZoneId?: string | null; + recurrenceId?: string | null; + location?: string | null; + sourceUrl?: string | null; + /** Format: date-time */ + sourceLastModifiedAt?: string | null; + /** Format: date-time */ + importedAt?: string; + }; + SocializeApiModulesCalendarIntegrationsHandlersListCalendarEventsRequest: Record; SocializeApiModulesCalendarIntegrationsHandlersListCalendarSourcesRequest: Record; + SocializeApiModulesCalendarIntegrationsHandlersUserCalendarExportFeedDto: { + isEnabled?: boolean; + feedUrl?: string | null; + /** Format: date-time */ + createdAt?: string | null; + /** Format: date-time */ + updatedAt?: string | null; + /** Format: date-time */ + revokedAt?: string | null; + }; SocializeApiModulesAssetsHandlersAssetRevisionDto: { /** Format: guid */ id?: string; @@ -2001,6 +2232,48 @@ export interface operations { }; }; }; + SocializeApiModulesOrganizationsHandlersChangeOrganizationLogoHandler: { + parameters: { + query?: never; + header?: never; + path: { + organizationId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "multipart/form-data": components["schemas"]["SocializeApiModulesOrganizationsHandlersChangeOrganizationLogoRequest"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SocializeApiModulesOrganizationsHandlersChangeOrganizationLogoResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/problem+json": components["schemas"]["FastEndpointsErrorResponse"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; SocializeApiModulesOrganizationsHandlersGetOrganizationHandler: { parameters: { query?: never; @@ -3353,6 +3626,35 @@ export interface operations { }; }; }; + SocializeApiModulesContentItemsHandlersGetContentItemActivityHandler: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SocializeApiModulesContentItemsHandlersContentItemActivityEntryDto"][]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; SocializeApiModulesContentItemsHandlersUpdateContentItemStatusHandler: { parameters: { query?: never; @@ -3433,7 +3735,7 @@ export interface operations { }; requestBody: { content: { - "application/json": components["schemas"]["SocializeApiModulesCommentsHandlersCreateCommentRequest"]; + "multipart/form-data": components["schemas"]["SocializeApiModulesCommentsHandlersCreateCommentRequest"]; }; }; responses: { @@ -3464,35 +3766,6 @@ export interface operations { }; }; }; - SocializeApiModulesCommentsHandlersResolveCommentHandler: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["SocializeApiModulesCommentsHandlersCommentDto"]; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - }; - }; SocializeApiModulesClientsHandlersChangeClientPortraitHandler: { parameters: { query?: never; @@ -3923,6 +4196,229 @@ export interface operations { }; }; }; + SocializeApiModulesCalendarIntegrationsHandlersListCalendarCatalogHandler: { + parameters: { + query?: { + search?: string | null; + country?: string | null; + region?: string | null; + language?: string | null; + category?: string | null; + cultureOrReligion?: string | null; + provider?: string | null; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SocializeApiModulesCalendarIntegrationsHandlersCalendarCatalogEntryDto"][]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + SocializeApiModulesCalendarIntegrationsHandlersListCalendarEventsHandler: { + parameters: { + query?: { + workspaceId?: string | null; + startDate?: string | null; + endDate?: string | null; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SocializeApiModulesCalendarIntegrationsHandlersCalendarEventDto"][]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + SocializeApiModulesCalendarIntegrationsHandlersRefreshCalendarSourceHandler: { + parameters: { + query?: never; + header?: never; + path: { + sourceId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SocializeApiModulesCalendarIntegrationsHandlersCalendarSourceDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + SocializeApiModulesCalendarIntegrationsHandlersGetUserCalendarExportFeedHandler: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SocializeApiModulesCalendarIntegrationsHandlersUserCalendarExportFeedDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + SocializeApiModulesCalendarIntegrationsHandlersRevokeUserCalendarExportFeedHandler: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SocializeApiModulesCalendarIntegrationsHandlersUserCalendarExportFeedDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + SocializeApiModulesCalendarIntegrationsHandlersEnableUserCalendarExportFeedHandler: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SocializeApiModulesCalendarIntegrationsHandlersUserCalendarExportFeedDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + SocializeApiModulesCalendarIntegrationsHandlersRegenerateUserCalendarExportFeedHandler: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SocializeApiModulesCalendarIntegrationsHandlersUserCalendarExportFeedDto"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + SocializeApiModulesCalendarIntegrationsHandlersGetUserCalendarExportFeedIcsHandler: { + parameters: { + query?: never; + header?: never; + path: { + token: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description No Content */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; SocializeApiModulesAssetsHandlersCreateAssetRevisionHandler: { parameters: { query?: never; diff --git a/frontend/src/assets/main.css b/frontend/src/assets/main.css index 462ec9a..eaa7e48 100644 --- a/frontend/src/assets/main.css +++ b/frontend/src/assets/main.css @@ -5,6 +5,10 @@ :root { --socialize-primary: #172033; --socialize-accent: #ff8a3d; + --socialize-accent-strong: #ef4444; + --socialize-brand-gradient: linear-gradient(135deg, var(--socialize-accent) 0%, var(--socialize-accent-strong) 100%); + --socialize-accent-shadow: rgba(255, 138, 61, 0.28); + --socialize-accent-strong-shadow: rgba(239, 68, 68, 0.28); --socialize-highlight: #2fa58d; --h-background: #f4f6f3; --h-on-background: #172033; diff --git a/frontend/src/features/auth/views/LoginView.vue b/frontend/src/features/auth/views/LoginView.vue index 5e11778..c6746da 100644 --- a/frontend/src/features/auth/views/LoginView.vue +++ b/frontend/src/features/auth/views/LoginView.vue @@ -218,7 +218,7 @@ .login-brand-mark { @apply flex h-11 w-11 items-center justify-center rounded-2xl text-lg font-black; - background: linear-gradient(135deg, #ff8a3d 0%, #ef4444 100%); + background: var(--socialize-brand-gradient); color: #fffaf2; } diff --git a/frontend/src/features/content/components/ColorPalette.vue b/frontend/src/features/content/components/ColorPalette.vue new file mode 100644 index 0000000..ab5afff --- /dev/null +++ b/frontend/src/features/content/components/ColorPalette.vue @@ -0,0 +1,69 @@ + + + + + diff --git a/frontend/src/features/content/components/ContentCommentComposer.vue b/frontend/src/features/content/components/ContentCommentComposer.vue new file mode 100644 index 0000000..78ba188 --- /dev/null +++ b/frontend/src/features/content/components/ContentCommentComposer.vue @@ -0,0 +1,389 @@ + + + + + diff --git a/frontend/src/features/content/components/ContentCommentFeed.vue b/frontend/src/features/content/components/ContentCommentFeed.vue new file mode 100644 index 0000000..4cfa3ae --- /dev/null +++ b/frontend/src/features/content/components/ContentCommentFeed.vue @@ -0,0 +1,386 @@ + + + + + diff --git a/frontend/src/features/content/stores/calendarIntegrationsStore.js b/frontend/src/features/content/stores/calendarIntegrationsStore.js index be8b7b7..40af032 100644 --- a/frontend/src/features/content/stores/calendarIntegrationsStore.js +++ b/frontend/src/features/content/stores/calendarIntegrationsStore.js @@ -128,6 +128,29 @@ export const useCalendarIntegrationsStore = defineStore('calendar-integrations', } } + async function updateSource(sourceId, payload) { + if (!sourceId) { + return null; + } + + error.value = null; + + try { + const response = await client.put(`/api/calendar-integrations/sources/${sourceId}`, payload); + const updatedSource = response.data; + if (updatedSource) { + sources.value = sources.value.map(source => + source.id === updatedSource.id ? updatedSource : source + ); + } + return updatedSource; + } catch (updateError) { + console.error('Failed to update calendar source:', updateError); + error.value = 'Failed to update calendar source.'; + throw updateError; + } + } + async function refreshSource(sourceId) { if (!sourceId) { return null; @@ -176,6 +199,7 @@ export const useCalendarIntegrationsStore = defineStore('calendar-integrations', fetchEvents, searchCatalog, createSource, + updateSource, refreshSource, toggleSourceVisibility, }; diff --git a/frontend/src/features/content/stores/contentItemDetailStore.js b/frontend/src/features/content/stores/contentItemDetailStore.js index 4b0a560..dd6d474 100644 --- a/frontend/src/features/content/stores/contentItemDetailStore.js +++ b/frontend/src/features/content/stores/contentItemDetailStore.js @@ -129,11 +129,8 @@ export const useContentItemDetailStore = defineStore('content-item-detail', () = actions.comment = true; try { - const response = await client.post('/api/comments', { - ...payload, - contentItemId, - workspaceId: currentItemWorkspaceId(), - }); + const requestPayload = buildCommentPayload(contentItemId, payload); + const response = await client.post('/api/comments', requestPayload); if (response.data) { comments.value = [...comments.value, response.data]; await fetchActivity(contentItemId); @@ -144,6 +141,22 @@ export const useContentItemDetailStore = defineStore('content-item-detail', () = } } + function buildCommentPayload(contentItemId, payload) { + const workspaceId = currentItemWorkspaceId(); + + const formData = new FormData(); + formData.append('workspaceId', workspaceId); + formData.append('contentItemId', contentItemId); + formData.append('body', payload.body ?? ''); + if (payload.parentCommentId) { + formData.append('parentCommentId', payload.parentCommentId); + } + if (payload.mediaFile) { + formData.append('attachment', payload.mediaFile, payload.mediaFile.name || 'comment-attachment'); + } + return formData; + } + async function submitDecision(contentItemId, approvalId, payload) { actions.decision = true; diff --git a/frontend/src/features/content/views/ContentItemDetailView.vue b/frontend/src/features/content/views/ContentItemDetailView.vue index e8b4de1..d2b78df 100644 --- a/frontend/src/features/content/views/ContentItemDetailView.vue +++ b/frontend/src/features/content/views/ContentItemDetailView.vue @@ -4,10 +4,11 @@ import { useRoute, useRouter } from 'vue-router'; import { useSessionStorage } from '@vueuse/core'; import { mdiArrowLeft } from '@mdi/js'; - import AppAvatar from '@/components/AppAvatar.vue'; import { useChannelsStore } from '@/features/channels/stores/channelsStore.js'; import { useClientsStore } from '@/features/clients/stores/clientsStore.js'; import ContentApprovalPanel from '@/features/content/components/ContentApprovalPanel.vue'; + import ContentCommentComposer from '@/features/content/components/ContentCommentComposer.vue'; + import ContentCommentFeed from '@/features/content/components/ContentCommentFeed.vue'; import { useCalendarIntegrationsStore } from '@/features/content/stores/calendarIntegrationsStore.js'; import { useContentItemDetailStore } from '@/features/content/stores/contentItemDetailStore.js'; import { useContentItemsStore } from '@/features/content/stores/contentItemsStore.js'; @@ -39,10 +40,6 @@ placements: [], }); - const commentForm = reactive({ - body: '', - }); - const assetForm = reactive({ assetType: 'Image', displayName: '', @@ -102,6 +99,11 @@ { key: 'assets', label: 'Assets', count: detailStore.assets.length }, { key: 'activity', label: 'Activity', count: detailStore.activity.length }, ]); + const workspaceMembers = computed(() => + contentWorkspaceId.value + ? workspaceStore.membersByWorkspace[contentWorkspaceId.value] ?? [] + : [] + ); const selectedDateKey = computed(() => /^\d{4}-\d{2}-\d{2}$/.test(form.dueDate) ? form.dueDate : ''); const contextAnchorDate = computed(() => selectedDateKey.value ? parseDateKey(selectedDateKey.value) : startOfDay(new Date())); const calendarFetchRange = computed(() => { @@ -450,13 +452,12 @@ await detailStore.submitDecision(contentItemId.value, approvalId, payload); } - async function submitComment() { - if (!contentItemId.value || !commentForm.body.trim()) { + async function submitComment(payload) { + if (!contentItemId.value || !payload?.body?.trim()) { return; } - await detailStore.addComment(contentItemId.value, { body: commentForm.body.trim() }); - commentForm.body = ''; + await detailStore.addComment(contentItemId.value, payload); } function inferGoogleDriveFileId(value) { @@ -674,6 +675,7 @@ await Promise.all([ calendarStore.fetchSources(workspaceId), calendarStore.fetchEvents({ workspaceId, startDate, endDate }), + workspaceStore.fetchMembers(workspaceId), ]); }, { immediate: true } @@ -1127,50 +1129,18 @@