diff --git a/api/src/Sozsoft.Platform.Application.Contracts/Hr/DepartmentDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/Hr/DepartmentDto.cs new file mode 100644 index 0000000..1255523 --- /dev/null +++ b/api/src/Sozsoft.Platform.Application.Contracts/Hr/DepartmentDto.cs @@ -0,0 +1,13 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace Sozsoft.Platform.Hr; + +public class DepartmentDto : FullAuditedEntityDto +{ + public Guid? TenantId { get; set; } + + public string Name { get; set; } + + public Guid? ParentId { get; set; } +} diff --git a/api/src/Sozsoft.Platform.Application.Contracts/Hr/JobPositionDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/Hr/JobPositionDto.cs new file mode 100644 index 0000000..5281d1b --- /dev/null +++ b/api/src/Sozsoft.Platform.Application.Contracts/Hr/JobPositionDto.cs @@ -0,0 +1,15 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace Sozsoft.Platform.Hr; + +public class JobPositionDto : FullAuditedEntityDto +{ + public Guid? TenantId { get; set; } + + public string Name { get; set; } + + public Guid DepartmentId { get; set; } + + public Guid? ParentId { get; set; } +} diff --git a/api/src/Sozsoft.Platform.Application.Contracts/Identity/Dto/UserInfoViewModel.cs b/api/src/Sozsoft.Platform.Application.Contracts/Identity/Dto/UserInfoViewModel.cs index 8f9845c..6386aa6 100644 --- a/api/src/Sozsoft.Platform.Application.Contracts/Identity/Dto/UserInfoViewModel.cs +++ b/api/src/Sozsoft.Platform.Application.Contracts/Identity/Dto/UserInfoViewModel.cs @@ -4,13 +4,15 @@ using Volo.Abp.ObjectExtending; namespace Sozsoft.Platform.Identity.Dto; -public class UserInfoViewModel: ExtensibleObject +public class UserInfoViewModel : ExtensibleObject { public Guid Id { get; set; } + public Guid? TenantId { get; set; } public string ConcurrencyStamp { get; set; } public string UserName { get; set; } public string Name { get; set; } public string Surname { get; set; } + public string FullName => $"{Name} {Surname}".TrimEnd(); public string Email { get; set; } public string PhoneNumber { get; set; } public bool IsActive { get; set; } diff --git a/api/src/Sozsoft.Platform.Application.Contracts/Intranet/AnnouncementDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/Intranet/AnnouncementDto.cs new file mode 100644 index 0000000..1959d3c --- /dev/null +++ b/api/src/Sozsoft.Platform.Application.Contracts/Intranet/AnnouncementDto.cs @@ -0,0 +1,23 @@ +using System; +using Sozsoft.Platform.Identity.Dto; +using Volo.Abp.Application.Dtos; + +namespace Sozsoft.Platform.Intranet; + +public class AnnouncementDto : FullAuditedEntityDto +{ + public Guid? TenantId { get; set; } + + public string Title { get; set; } + public string Excerpt { get; set; } + public string Content { get; set; } + public string ImageUrl { get; set; } + public string Category { get; set; } + public Guid? UserId { get; set; } + public UserInfoViewModel User { get; set; } + public DateTime PublishDate { get; set; } + public DateTime? ExpiryDate { get; set; } + public bool IsPinned { get; set; } + public int ViewCount { get; set; } + public string Attachments { get; set; } +} diff --git a/api/src/Sozsoft.Platform.Application.Contracts/Intranet/IIntranetAppService.cs b/api/src/Sozsoft.Platform.Application.Contracts/Intranet/IIntranetAppService.cs new file mode 100644 index 0000000..8a11e8e --- /dev/null +++ b/api/src/Sozsoft.Platform.Application.Contracts/Intranet/IIntranetAppService.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace Sozsoft.Platform.Intranet; + +public interface IIntranetAppService : IApplicationService +{ + Task GetIntranetDashboardAsync(); +} diff --git a/api/src/Sozsoft.Platform.Application.Contracts/Intranet/IntranetDashboardDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/Intranet/IntranetDashboardDto.cs new file mode 100644 index 0000000..cd9baff --- /dev/null +++ b/api/src/Sozsoft.Platform.Application.Contracts/Intranet/IntranetDashboardDto.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Sozsoft.Platform.FileManagement; +using Sozsoft.Platform.Identity.Dto; + +namespace Sozsoft.Platform.Intranet; + +public class IntranetDashboardDto +{ + public List Birthdays { get; set; } = []; + public List Documents { get; set; } = []; + public List Announcements { get; set; } = []; + public List Surveys { get; set; } = []; + public List SocialPosts { get; set; } = []; +} diff --git a/api/src/Sozsoft.Platform.Application.Contracts/Intranet/SocialPostDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/Intranet/SocialPostDto.cs new file mode 100644 index 0000000..a34d43d --- /dev/null +++ b/api/src/Sozsoft.Platform.Application.Contracts/Intranet/SocialPostDto.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using Sozsoft.Platform.Identity.Dto; +using Volo.Abp.Application.Dtos; + +namespace Sozsoft.Platform.Intranet; + +public class SocialPostDto : FullAuditedEntityDto +{ + public Guid? UserId { get; set; } + public UserInfoViewModel? User { get; set; } + public string Content { get; set; } + + public int LikeCount { get; set; } + public bool IsLiked { get; set; } + public bool IsOwnPost { get; set; } + + public SocialLocationDto? Location { get; set; } + public SocialMediaDto? Media { get; set; } + public List Comments { get; set; } + public List Likes { get; set; } +} + +public class SocialLocationDto : FullAuditedEntityDto +{ + public Guid SocialPostId { get; set; } + public string Name { get; set; } + public string? Address { get; set; } + public double? Lat { get; set; } + public double? Lng { get; set; } + public string? PlaceId { get; set; } +} + +public class SocialMediaDto : FullAuditedEntityDto +{ + public Guid SocialPostId { get; set; } + public string Type { get; set; } // image | video | poll + public string[] Urls { get; set; } + + // Poll Fields + public string? PollQuestion { get; set; } + public int? PollTotalVotes { get; set; } + public DateTime? PollEndsAt { get; set; } + public string? PollUserVoteId { get; set; } + + public List PollOptions { get; set; } +} + +public class SocialPollOptionDto : FullAuditedEntityDto +{ + public Guid SocialMediaId { get; set; } + public string Text { get; set; } + public int Votes { get; set; } +} + +public class SocialCommentDto : FullAuditedEntityDto +{ + public Guid SocialPostId { get; set; } + public Guid? UserId { get; set; } + public UserInfoViewModel? User { get; set; } + public string Content { get; set; } +} + +public class SocialLikeDto : FullAuditedEntityDto +{ + public Guid SocialPostId { get; set; } + public Guid? UserId { get; set; } + public UserInfoViewModel? User { get; set; } +} diff --git a/api/src/Sozsoft.Platform.Application.Contracts/Intranet/SurveyDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/Intranet/SurveyDto.cs new file mode 100644 index 0000000..f2e6bd6 --- /dev/null +++ b/api/src/Sozsoft.Platform.Application.Contracts/Intranet/SurveyDto.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Application.Dtos; + +namespace Sozsoft.Platform.Intranet; + +public class SurveyDto : FullAuditedEntityDto +{ + public string Title { get; set; } + public string Description { get; set; } + public DateTime Deadline { get; set; } + public int Responses { get; set; } + public string Status { get; set; } // draft | active | closed + public bool IsAnonymous { get; set; } + + public List Questions { get; set; } +} + +public class SurveyQuestionDto : FullAuditedEntityDto +{ + public Guid SurveyId { get; set; } + public string QuestionText { get; set; } + public string Type { get; set; } // rating | multiple-choice | text | textarea | yes-no + public int Order { get; set; } + public bool IsRequired { get; set; } + + public List Options { get; set; } +} + +public class SurveyQuestionOptionDto : FullAuditedEntityDto +{ + public Guid QuestionId { get; set; } + public string Text { get; set; } + public int Order { get; set; } +} + +public class SurveyResponseDto : FullAuditedEntityDto +{ + public Guid SurveyId { get; set; } + public Guid? UserId { get; set; } + public DateTime SubmissionTime { get; set; } + + public List Answers { get; set; } +} + +public class SurveyAnswerDto : FullAuditedEntityDto +{ + public Guid ResponseId { get; set; } + public Guid QuestionId { get; set; } + public string QuestionType { get; set; } + public string Value { get; set; } +} diff --git a/api/src/Sozsoft.Platform.Application.Contracts/Public/IBlogAppService.cs b/api/src/Sozsoft.Platform.Application.Contracts/Public/IBlogAppService.cs index d32ac2f..4209a66 100644 --- a/api/src/Sozsoft.Platform.Application.Contracts/Public/IBlogAppService.cs +++ b/api/src/Sozsoft.Platform.Application.Contracts/Public/IBlogAppService.cs @@ -33,7 +33,7 @@ public class SearchBlogPostsInput : PagedAndSortedResultRequestDto public string Query { get; set; } public Guid? CategoryId { get; set; } public string Tag { get; set; } - public Guid? EmployeeId { get; set; } + public Guid? UserId { get; set; } public bool? IsPublished { get; set; } } diff --git a/api/src/Sozsoft.Platform.Application/Hr/HrAutoMapperProfile.cs b/api/src/Sozsoft.Platform.Application/Hr/HrAutoMapperProfile.cs new file mode 100644 index 0000000..83a7020 --- /dev/null +++ b/api/src/Sozsoft.Platform.Application/Hr/HrAutoMapperProfile.cs @@ -0,0 +1,15 @@ +using AutoMapper; +using Sozsoft.Platform.Entities; +using Sozsoft.Platform.Hr; + +namespace Sozsoft.Platform.Intranet; + +public class HrAutoMapperProfile : Profile +{ + public HrAutoMapperProfile() + { + CreateMap(); + CreateMap(); + } +} + diff --git a/api/src/Sozsoft.Platform.Application/Identity/IdentityAutoMapperProfile.cs b/api/src/Sozsoft.Platform.Application/Identity/IdentityAutoMapperProfile.cs index f3e6bf7..6c3dfd1 100644 --- a/api/src/Sozsoft.Platform.Application/Identity/IdentityAutoMapperProfile.cs +++ b/api/src/Sozsoft.Platform.Application/Identity/IdentityAutoMapperProfile.cs @@ -11,7 +11,14 @@ public class IdentityAutoMapperProfile : Profile { public IdentityAutoMapperProfile() { - CreateMap(); + CreateMap() + .ForMember(dest => dest.Roles, opt => opt.Ignore()) + .ForMember(dest => dest.Branches, opt => opt.Ignore()) + .ForMember(dest => dest.Claims, opt => opt.Ignore()) + .ForMember(dest => dest.WorkHours, opt => opt.Ignore()) + .ForMember(dest => dest.Departments, opt => opt.Ignore()) + .ForMember(dest => dest.JobPositions, opt => opt.Ignore()) + .ForMember(dest => dest.userRoleNames, opt => opt.Ignore()); CreateMap(); CreateMap(); CreateMap(); diff --git a/api/src/Sozsoft.Platform.Application/Intranet/IntranetAppService.cs b/api/src/Sozsoft.Platform.Application/Intranet/IntranetAppService.cs new file mode 100644 index 0000000..5899ba8 --- /dev/null +++ b/api/src/Sozsoft.Platform.Application/Intranet/IntranetAppService.cs @@ -0,0 +1,350 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Sozsoft.Platform.BlobStoring; +using Sozsoft.Platform.Entities; +using Sozsoft.Platform.FileManagement; +using Sozsoft.Platform.Identity.Dto; +using Sozsoft.Platform.Extensions; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Identity; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Uow; + +namespace Sozsoft.Platform.Intranet; + +[Authorize] +public class IntranetAppService : PlatformAppService, IIntranetAppService +{ + private readonly ICurrentTenant _currentTenant; + private readonly BlobManager _blobContainer; + private readonly IConfiguration _configuration; + + private readonly IIdentityUserAppService _identityUserAppService; + private readonly IIdentityUserRepository _identityUserRepository; + private readonly IRepository _departmentRepository; + private readonly IRepository _jobPositionRepository; + private readonly IRepository _announcementRepository; + private readonly IRepository _surveyRepository; + private readonly IRepository _socialPostRepository; + + public IntranetAppService( + ICurrentTenant currentTenant, + BlobManager blobContainer, + IConfiguration configuration, + + IIdentityUserAppService identityUserAppService, + IIdentityUserRepository identityUserRepository, + IRepository departmentRepository, + IRepository jobPositionRepository, + IRepository announcementRepository, + IRepository surveyRepository, + IRepository socialPostRepository + ) + { + _currentTenant = currentTenant; + _blobContainer = blobContainer; + _configuration = configuration; + _identityUserAppService = identityUserAppService; + _identityUserRepository = identityUserRepository; + _departmentRepository = departmentRepository; + _jobPositionRepository = jobPositionRepository; + _announcementRepository = announcementRepository; + _surveyRepository = surveyRepository; + _socialPostRepository = socialPostRepository; + } + + [UnitOfWork] + public async Task GetIntranetDashboardAsync() + { + return new IntranetDashboardDto + { + Birthdays = await GetBirthdaysAsync(), //1 + Documents = await GetIntranetDocumentsAsync(BlobContainerNames.Intranet), //2 + Announcements = await GetAnnouncementsAsync(), //3 + Surveys = await GetSurveysAsync(), //4 + SocialPosts = await GetSocialPostsAsync(), //5 + }; + } + + private async Task> GetBirthdaysAsync() + { + var today = DateTime.Now; + + var users = await _identityUserRepository.GetListAsync(); + + var userList = users + .Where(u => + { + var birthDate = u.GetBirthDate(); + return birthDate.HasValue + && birthDate.Value.Day == today.Day + && birthDate.Value.Month == today.Month; + }) + .ToList(); + + var allDepartments = await _departmentRepository.GetListAsync(); + var departmentDict = allDepartments.ToDictionary(d => d.Id, d => d.Name); + + var allJobPositions = await _jobPositionRepository.GetListAsync(); + var jobPositionDict = allJobPositions.ToDictionary(j => j.Id, j => j); + + var result = ObjectMapper.Map, List>(userList); + + for (var i = 0; i < userList.Count; i++) + { + var user = userList[i]; + + result[i].BirthDate = user.GetBirthDate(); + result[i].WorkHour = user.GetWorkHour(); + result[i].Nationality = user.GetNationality(); + + var deptId = user.GetDepartmentId(); + if (deptId != Guid.Empty && departmentDict.TryGetValue(deptId, out var deptName)) + { + result[i].DepartmentId = deptId; + result[i].Departments = + [ + new AssignedDepartmentViewModel { Id = deptId, Name = deptName, IsAssigned = true } + ]; + } + + var jobPosId = user.GetJobPositionId(); + if (jobPosId != Guid.Empty && jobPositionDict.TryGetValue(jobPosId, out var jobPosition)) + { + result[i].JobPositionId = jobPosId; + result[i].JobPositions = + [ + new AssignedJobPoisitionViewModel { Id = jobPosId, Name = jobPosition.Name, DepartmentId = jobPosition.DepartmentId, IsAssigned = true } + ]; + } + } + + return result; + } + + private async Task> GetAnnouncementsAsync() + { + var announcements = await _announcementRepository.GetListAsync(); + var announcementDtos = new List(); + + var allDepartments = await _departmentRepository.GetListAsync(); + var departmentDict = allDepartments.ToDictionary(d => d.Id, d => d.Name); + + var allJobPositions = await _jobPositionRepository.GetListAsync(); + var jobPositionDict = allJobPositions.ToDictionary(j => j.Id, j => j); + + foreach (var announcement in announcements) + { + var dto = ObjectMapper.Map(announcement); + + var user = await _identityUserRepository.FindAsync(announcement.UserId ?? Guid.Empty); + if (user != null) + { + var userVm = ObjectMapper.Map(user); + + userVm.BirthDate = user.GetBirthDate(); + userVm.WorkHour = user.GetWorkHour(); + userVm.Nationality = user.GetNationality(); + + var deptId = user.GetDepartmentId(); + if (deptId != Guid.Empty && departmentDict.TryGetValue(deptId, out var deptName)) + { + userVm.DepartmentId = deptId; + userVm.Departments = + [ + new AssignedDepartmentViewModel { Id = deptId, Name = deptName, IsAssigned = true } + ]; + } + + var jobPosId = user.GetJobPositionId(); + if (jobPosId != Guid.Empty && jobPositionDict.TryGetValue(jobPosId, out var jobPosition)) + { + userVm.JobPositionId = jobPosId; + userVm.JobPositions = + [ + new AssignedJobPoisitionViewModel { Id = jobPosId, Name = jobPosition.Name, DepartmentId = jobPosition.DepartmentId, IsAssigned = true } + ]; + } + + dto.User = userVm; + } + + announcementDtos.Add(dto); + } + + return announcementDtos; + } + + private async Task> GetSurveysAsync() + { + var queryable = await _surveyRepository.GetQueryableAsync(); + + var surveys = await AsyncExecuter.ToListAsync( + queryable + .Where(s => s.Status == "active") + .Include(s => s.Questions) + .ThenInclude(q => q.Options) + ); + + return ObjectMapper.Map, List>(surveys); + } + + private async Task> GetSocialPostsAsync() + { + var queryable = await _socialPostRepository + .WithDetailsAsync(e => e.Location, e => e.Media, e => e.Comments, e => e.Likes); + + var socialPosts = await AsyncExecuter.ToListAsync(queryable); + + var dtos = ObjectMapper.Map, List>(socialPosts); + + // Collect all unique user IDs to resolve in a single query + var userIds = dtos + .Select(p => p.UserId) + .Union(dtos.SelectMany(p => p.Comments.Select(c => c.UserId))) + .Union(dtos.SelectMany(p => p.Likes.Select(l => l.UserId))) + .Where(id => id.HasValue) + .Select(id => id!.Value) + .Distinct() + .ToList(); + + if (userIds.Count > 0) + { + var allDepartments = await _departmentRepository.GetListAsync(); + var departmentDict = allDepartments.ToDictionary(d => d.Id, d => d.Name); + + var allJobPositions = await _jobPositionRepository.GetListAsync(); + var jobPositionDict = allJobPositions.ToDictionary(j => j.Id, j => j); + + var users = await _identityUserRepository.GetListAsync(); + var userMap = users + .Where(u => userIds.Contains(u.Id)) + .ToDictionary(u => u.Id, u => + { + var vm = ObjectMapper.Map(u); + vm.BirthDate = u.GetBirthDate(); + vm.WorkHour = u.GetWorkHour(); + vm.Nationality = u.GetNationality(); + + var deptId = u.GetDepartmentId(); + if (deptId != Guid.Empty && departmentDict.TryGetValue(deptId, out var deptName)) + { + vm.DepartmentId = deptId; + vm.Departments = + [ + new AssignedDepartmentViewModel { Id = deptId, Name = deptName, IsAssigned = true } + ]; + } + + var jobPosId = u.GetJobPositionId(); + if (jobPosId != Guid.Empty && jobPositionDict.TryGetValue(jobPosId, out var jobPosition)) + { + vm.JobPositionId = jobPosId; + vm.JobPositions = + [ + new AssignedJobPoisitionViewModel { Id = jobPosId, Name = jobPosition.Name, DepartmentId = jobPosition.DepartmentId, IsAssigned = true } + ]; + } + + return vm; + }); + + foreach (var dto in dtos) + { + if (dto.UserId.HasValue && userMap.TryGetValue(dto.UserId.Value, out var postUser)) + dto.User = postUser; + + foreach (var comment in dto.Comments) + if (comment.UserId.HasValue && userMap.TryGetValue(comment.UserId.Value, out var commentUser)) + comment.User = commentUser; + + foreach (var like in dto.Likes) + if (like.UserId.HasValue && userMap.TryGetValue(like.UserId.Value, out var likeUser)) + like.User = likeUser; + } + } + + return dtos; + } + + public async Task> GetIntranetDocumentsAsync(string folderPath) + { + var items = new List(); + var cdnBasePath = _configuration["App:CdnPath"]; + + if (string.IsNullOrEmpty(cdnBasePath)) + { + Logger.LogWarning("CDN path is not configured"); + return items; + } + + var tenantId = _currentTenant.Id?.ToString() ?? "host"; + var fullPath = Path.Combine(cdnBasePath, tenantId); + + if (!string.IsNullOrEmpty(folderPath)) + { + fullPath = Path.Combine(fullPath, folderPath); + } + + if (!Directory.Exists(fullPath)) + { + Logger.LogWarning($"Directory not found: {fullPath}"); + return items; + } + + var files = Directory.GetFiles(fullPath); + foreach (var file in files) + { + var fileInfo = new FileInfo(file); + var relativePath = string.IsNullOrEmpty(folderPath) ? fileInfo.Name : $"{folderPath}/{fileInfo.Name}"; + + items.Add(new FileItemDto + { + Id = Guid.NewGuid().ToString(), + Name = fileInfo.Name, + Type = "file", + Size = fileInfo.Length, + Extension = fileInfo.Extension, + MimeType = GetMimeType(fileInfo.Extension), + CreatedAt = fileInfo.CreationTime, + ModifiedAt = fileInfo.LastWriteTime, + Path = relativePath, + ParentId = string.Empty, + IsReadOnly = false, + ChildCount = 0, + TenantId = _currentTenant.Id?.ToString() + }); + } + + return items.OrderBy(x => x.Name).ToList(); + } + + private string GetMimeType(string extension) + { + return extension.ToLowerInvariant() switch + { + ".pdf" => "application/pdf", + ".doc" => "application/msword", + ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ".xls" => "application/vnd.ms-excel", + ".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ".ppt" => "application/vnd.ms-powerpoint", + ".pptx" => "application/vnd.openxmlformats-officedocument.presentationml.presentation", + ".jpg" or ".jpeg" => "image/jpeg", + ".png" => "image/png", + ".gif" => "image/gif", + ".txt" => "text/plain", + ".zip" => "application/zip", + ".rar" => "application/x-rar-compressed", + _ => "application/octet-stream" + }; + } +} + diff --git a/api/src/Sozsoft.Platform.Application/Intranet/IntranetAutoMapperProfile.cs b/api/src/Sozsoft.Platform.Application/Intranet/IntranetAutoMapperProfile.cs new file mode 100644 index 0000000..a82385c --- /dev/null +++ b/api/src/Sozsoft.Platform.Application/Intranet/IntranetAutoMapperProfile.cs @@ -0,0 +1,25 @@ +using AutoMapper; +using Sozsoft.Platform.Entities; + +namespace Sozsoft.Platform.Intranet; + +public class IntranetAutoMapperProfile : Profile +{ + public IntranetAutoMapperProfile() + { + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + } +} + diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json b/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json index cb9a45e..0080cac 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json @@ -138,12 +138,6 @@ "en": "Administration", "tr": "Yönetim" }, - { - "resourceName": "Platform", - "key": "App.Intranet", - "en": "Intranet", - "tr": "Intranet" - }, { "resourceName": "Platform", "key": "App.SupplyChain", @@ -3644,6 +3638,12 @@ "en": "Audit Logs", "tr": "Audit Günlükleri" }, + { + "resourceName": "Platform", + "key": "App.Intranet", + "en": "Intranet", + "tr": "Intranet" + }, { "resourceName": "Platform", "key": "App.AuditLogs.FetchFailed", @@ -6092,6 +6092,12 @@ "tr": "Eğitim Durumu", "en": "Education Status" }, + { + "resourceName": "Platform", + "key": "App.Intranet.SocialComment", + "tr": "Sosyal Yorumlar", + "en": "Social Comments" + }, { "resourceName": "Platform", "key": "App.Intranet.Events", @@ -12284,6 +12290,12 @@ "tr": "Acil", "en": "Urgent" }, + { + "resourceName": "Platform", + "key": "App.Platform.Intranet.Widgets.ActiveSurveys.Questions", + "tr": "Sorular", + "en": "Questions" + }, { "resourceName": "Platform", "key": "App.Platform.Intranet.Widgets.ActiveSurveys.Title", diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/PermissionsData.json b/api/src/Sozsoft.Platform.DbMigrator/Seeds/PermissionsData.json index 25a8c13..90e9332 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/PermissionsData.json +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/PermissionsData.json @@ -2989,6 +2989,15 @@ "MultiTenancySide": 3, "MenuGroup": "Erp|Kurs" }, + { + "GroupName": "App.Administration", + "Name": "AbpIdentity.Users.Widget", + "ParentName": "AbpIdentity.Users", + "DisplayName": "Widget", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Erp|Kurs" + }, { "GroupName": "App.Administration", "Name": "AbpIdentity.Users.Update.ManageRoles", @@ -3304,6 +3313,15 @@ "MultiTenancySide": 3, "MenuGroup": "Erp|Kurs" }, + { + "GroupName": "App.Administration", + "Name": "App.Files.Widget", + "ParentName": "App.Files", + "DisplayName": "Widget", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Erp|Kurs" + }, { "GroupName": "App.Administration", "Name": "App.ForumManagement.Publish", @@ -3312,6 +3330,429 @@ "IsEnabled": true, "MultiTenancySide": 3, "MenuGroup": "Erp|Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet", + "ParentName": null, + "DisplayName": "App.Intranet", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Erp|Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventType", + "ParentName": "App.Intranet", + "DisplayName": "App.Intranet.Events.EventType", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventType.Create", + "ParentName": "App.Intranet.Events.EventType", + "DisplayName": "Create", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventType.Update", + "ParentName": "App.Intranet.Events.EventType", + "DisplayName": "Update", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventType.Delete", + "ParentName": "App.Intranet.Events.EventType", + "DisplayName": "Delete", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventType.Export", + "ParentName": "App.Intranet.Events.EventType", + "DisplayName": "Export", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventType.Import", + "ParentName": "App.Intranet.Events.EventType", + "DisplayName": "Import", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventType.Note", + "ParentName": "App.Intranet.Events.EventType", + "DisplayName": "Note", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventCategory", + "ParentName": "App.Intranet", + "DisplayName": "App.Intranet.Events.EventCategory", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventCategory.Create", + "ParentName": "App.Intranet.Events.EventCategory", + "DisplayName": "Create", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventCategory.Update", + "ParentName": "App.Intranet.Events.EventCategory", + "DisplayName": "Update", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventCategory.Delete", + "ParentName": "App.Intranet.Events.EventCategory", + "DisplayName": "Delete", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventCategory.Export", + "ParentName": "App.Intranet.Events.EventCategory", + "DisplayName": "Export", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventCategory.Import", + "ParentName": "App.Intranet.Events.EventCategory", + "DisplayName": "Import", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.EventCategory.Note", + "ParentName": "App.Intranet.Events.EventCategory", + "DisplayName": "Note", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.Event", + "ParentName": "App.Intranet", + "DisplayName": "App.Intranet.Events.Event", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.Event.Create", + "ParentName": "App.Intranet.Events.Event", + "DisplayName": "Create", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.Event.Update", + "ParentName": "App.Intranet.Events.Event", + "DisplayName": "Update", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.Event.Delete", + "ParentName": "App.Intranet.Events.Event", + "DisplayName": "Delete", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.Event.Export", + "ParentName": "App.Intranet.Events.Event", + "DisplayName": "Export", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.Event.Import", + "ParentName": "App.Intranet.Events.Event", + "DisplayName": "Import", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.Event.Note", + "ParentName": "App.Intranet.Events.Event", + "DisplayName": "Note", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Events.Event.Widget", + "ParentName": "App.Intranet.Events.Event", + "DisplayName": "Widget", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Announcement", + "ParentName": "App.Intranet", + "DisplayName": "App.Intranet.Announcement", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Announcement.Create", + "ParentName": "App.Intranet.Announcement", + "DisplayName": "Create", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Announcement.Update", + "ParentName": "App.Intranet.Announcement", + "DisplayName": "Update", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Announcement.Delete", + "ParentName": "App.Intranet.Announcement", + "DisplayName": "Delete", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Announcement.Export", + "ParentName": "App.Intranet.Announcement", + "DisplayName": "Export", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Announcement.Import", + "ParentName": "App.Intranet.Announcement", + "DisplayName": "Import", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Announcement.Note", + "ParentName": "App.Intranet.Announcement", + "DisplayName": "Note", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Announcement.Widget", + "ParentName": "App.Intranet.Announcement", + "DisplayName": "Widget", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialPost", + "ParentName": "App.Intranet", + "DisplayName": "App.Intranet.SocialPost", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialPost.Create", + "ParentName": "App.Intranet.SocialPost", + "DisplayName": "Create", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialPost.Update", + "ParentName": "App.Intranet.SocialPost", + "DisplayName": "Update", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialPost.Delete", + "ParentName": "App.Intranet.SocialPost", + "DisplayName": "Delete", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialPost.Export", + "ParentName": "App.Intranet.SocialPost", + "DisplayName": "Export", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialPost.Import", + "ParentName": "App.Intranet.SocialPost", + "DisplayName": "Import", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialPost.Note", + "ParentName": "App.Intranet.SocialPost", + "DisplayName": "Note", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialPost.Widget", + "ParentName": "App.Intranet.SocialPost", + "DisplayName": "Widget", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialComment", + "ParentName": "App.Intranet", + "DisplayName": "App.Intranet.SocialComment", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialComment.Create", + "ParentName": "App.Intranet.SocialComment", + "DisplayName": "Create", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialComment.Update", + "ParentName": "App.Intranet.SocialComment", + "DisplayName": "Update", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialComment.Delete", + "ParentName": "App.Intranet.SocialComment", + "DisplayName": "Delete", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialComment.Export", + "ParentName": "App.Intranet.SocialComment", + "DisplayName": "Export", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialComment.Import", + "ParentName": "App.Intranet.SocialComment", + "DisplayName": "Import", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.SocialComment.Note", + "ParentName": "App.Intranet.SocialComment", + "DisplayName": "Note", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Kurs" + }, + { + "GroupName": "App.Administration", + "Name": "App.Intranet.Survey.Widget", + "ParentName": "App.Intranet", + "DisplayName": "App.Intranet.Survey.Widget", + "IsEnabled": true, + "MultiTenancySide": 3, + "MenuGroup": "Erp|Kurs" } ] } \ No newline at end of file diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/WizardDataSeeder.cs b/api/src/Sozsoft.Platform.DbMigrator/Seeds/WizardDataSeeder.cs index 75cb131..a36b898 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/WizardDataSeeder.cs +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/WizardDataSeeder.cs @@ -70,14 +70,14 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency var wizardDataPath = Path.Combine(Directory.GetCurrentDirectory(), "Seeds", "WizardData"); if (!Directory.Exists(wizardDataPath)) { - _logger.LogInformation("Seeds/WizardData directory not found, skipping."); + _logger.LogInformation("WizardData directory not found, skipping."); return; } var jsonFiles = Directory.GetFiles(wizardDataPath, "*.json").OrderBy(f => Path.GetFileName(f)).ToArray(); if (jsonFiles.Length == 0) { - _logger.LogInformation("No JSON files found in Seeds/WizardData directory, skipping."); + _logger.LogInformation("No JSON files found in WizardData directory, skipping."); return; } diff --git a/api/src/Sozsoft.Platform.Domain.Shared/Enums/TableNameEnum.cs b/api/src/Sozsoft.Platform.Domain.Shared/Enums/TableNameEnum.cs index ea64f90..a675613 100644 --- a/api/src/Sozsoft.Platform.Domain.Shared/Enums/TableNameEnum.cs +++ b/api/src/Sozsoft.Platform.Domain.Shared/Enums/TableNameEnum.cs @@ -64,4 +64,16 @@ public enum TableNameEnum BlogPost, Demo, Contact, + Announcement, + Survey, + SurveyQuestion, + SurveyQuestionOption, + SurveyResponse, + SurveyAnswer, + SocialPost, + SocialLocation, + SocialMedia, + SocialPollOption, + SocialComment, + SocialLike } diff --git a/api/src/Sozsoft.Platform.Domain.Shared/TableNameResolver.cs b/api/src/Sozsoft.Platform.Domain.Shared/TableNameResolver.cs index c8aa76c..bc4dc1b 100644 --- a/api/src/Sozsoft.Platform.Domain.Shared/TableNameResolver.cs +++ b/api/src/Sozsoft.Platform.Domain.Shared/TableNameResolver.cs @@ -76,6 +76,21 @@ public static class TableNameResolver { nameof(TableNameEnum.Note), (TablePrefix.TenantByName, MenuPrefix.Administration) }, { nameof(TableNameEnum.ReportCategory), (TablePrefix.TenantByName, MenuPrefix.Administration) }, { nameof(TableNameEnum.ReportTemplate), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + + // 🔹 INTRANET TABLOLARI + { nameof(TableNameEnum.Announcement), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + { nameof(TableNameEnum.Survey), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + { nameof(TableNameEnum.SurveyQuestion), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + { nameof(TableNameEnum.SurveyQuestionOption), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + { nameof(TableNameEnum.SurveyResponse), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + { nameof(TableNameEnum.SurveyAnswer), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + { nameof(TableNameEnum.SocialPost), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + { nameof(TableNameEnum.SocialLocation), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + { nameof(TableNameEnum.SocialMedia), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + { nameof(TableNameEnum.SocialPollOption), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + { nameof(TableNameEnum.SocialComment), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + { nameof(TableNameEnum.SocialLike), (TablePrefix.TenantByName, MenuPrefix.Administration) }, + }; public static string GetFullTableName(string tableName) diff --git a/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Definitions/Announcement.cs b/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Definitions/Announcement.cs new file mode 100644 index 0000000..e3f91dd --- /dev/null +++ b/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Definitions/Announcement.cs @@ -0,0 +1,23 @@ +using System; +using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.MultiTenancy; + +namespace Sozsoft.Platform.Entities; + +public class Announcement : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public string Title { get; set; } + public string Excerpt { get; set; } + public string Content { get; set; } + public string ImageUrl { get; set; } + public string Category { get; set; } + public Guid? UserId { get; set; } + public DateTime PublishDate { get; set; } + public DateTime? ExpiryDate { get; set; } + public bool IsPinned { get; set; } + public int ViewCount { get; set; } + public string Attachments { get; set; } +} + diff --git a/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Definitions/SocialPost.cs b/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Definitions/SocialPost.cs new file mode 100644 index 0000000..fa03308 --- /dev/null +++ b/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Definitions/SocialPost.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.MultiTenancy; + +namespace Sozsoft.Platform.Entities; + +public class SocialPost : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid? UserId { get; set; } + + public string Content { get; set; } + + public int LikeCount { get; set; } + public bool IsLiked { get; set; } + public bool IsOwnPost { get; set; } + + // Relations + public SocialLocation Location { get; set; } + public SocialMedia Media { get; set; } + public ICollection Comments { get; set; } + public ICollection Likes { get; set; } +} + +public class SocialLocation : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid SocialPostId { get; set; } + public SocialPost SocialPost { get; set; } + + public string Name { get; set; } + public string? Address { get; set; } + public double? Lat { get; set; } + public double? Lng { get; set; } + public string? PlaceId { get; set; } +} + +public class SocialMedia : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid SocialPostId { get; set; } + public SocialPost SocialPost { get; set; } + + public string Type { get; set; } // image | video | poll + public string[] Urls { get; set; } + + // Poll fields + public string? PollQuestion { get; set; } + public int? PollTotalVotes { get; set; } + public DateTime? PollEndsAt { get; set; } + public string? PollUserVoteId { get; set; } + + public ICollection PollOptions { get; set; } +} + +public class SocialPollOption : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid SocialMediaId { get; set; } + public SocialMedia SocialMedia { get; set; } + + public string Text { get; set; } + public int Votes { get; set; } +} + +public class SocialComment : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid SocialPostId { get; set; } + public SocialPost SocialPost { get; set; } + + public Guid? UserId { get; set; } + + public string Content { get; set; } +} + +public class SocialLike : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid SocialPostId { get; set; } + public SocialPost SocialPost { get; set; } + + public Guid? UserId { get; set; } +} diff --git a/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Definitions/Survey.cs b/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Definitions/Survey.cs new file mode 100644 index 0000000..ab402f8 --- /dev/null +++ b/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Definitions/Survey.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using Microsoft.AspNetCore.Identity; +using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.MultiTenancy; + +namespace Sozsoft.Platform.Entities; + +public class Survey : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public string Title { get; set; } + public string Description { get; set; } + public DateTime Deadline { get; set; } + public int Responses { get; set; } + public string Status { get; set; } // draft | active | closed + public bool IsAnonymous { get; set; } + + public ICollection Questions { get; set; } + public ICollection SurveyResponses { get; set; } +} + +public class SurveyQuestion : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid SurveyId { get; set; } + public Survey Survey { get; set; } + + public string QuestionText { get; set; } + public string Type { get; set; } // rating | multiple-choice | text | textarea | yes-no + public int Order { get; set; } + public bool IsRequired { get; set; } + + public ICollection Options { get; set; } +} + +public class SurveyQuestionOption : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid QuestionId { get; set; } + public SurveyQuestion Question { get; set; } + + public string Text { get; set; } + public int Order { get; set; } +} + +public class SurveyResponse : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid SurveyId { get; set; } + public Survey Survey { get; set; } + + public Guid? UserId { get; set; } + + public DateTime SubmissionTime { get; set; } + + public ICollection Answers { get; set; } +} + +public class SurveyAnswer : FullAuditedEntity, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid ResponseId { get; set; } + public SurveyResponse Response { get; set; } + + public Guid QuestionId { get; set; } + public SurveyQuestion Question { get; set; } + + public string QuestionType { get; set; } // rating | multiple-choice | text | textarea | yes-no + public string Value { get; set; } +} diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs index b77fc27..3393e85 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs @@ -109,6 +109,23 @@ public class PlatformDbContext : public DbSet JobPositions { get; set; } #endregion + #region Intranet + public DbSet Announcements { get; set; } + + public DbSet Surveys { get; set; } + public DbSet SurveyQuestions { get; set; } + public DbSet SurveyQuestionOptions { get; set; } + public DbSet SurveyResponses { get; set; } + public DbSet SurveyAnswers { get; set; } + + public DbSet SocialPosts { get; set; } + public DbSet SocialLocations { get; set; } + public DbSet SocialMedias { get; set; } + public DbSet SocialPollOptions { get; set; } + public DbSet SocialComments { get; set; } + public DbSet SocialLikes { get; set; } + #endregion + public PlatformDbContext(DbContextOptions options) : base(options) { @@ -1026,5 +1043,171 @@ public class PlatformDbContext : b.Property(x => x.PrimaryEntityType).HasMaxLength(256); b.Property(x => x.ControllerName).HasMaxLength(256); }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.Announcement)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.Title).IsRequired().HasMaxLength(256); + b.Property(x => x.Excerpt).IsRequired().HasMaxLength(512); + b.Property(x => x.Content).IsRequired().HasMaxLength(4096); + b.Property(x => x.ImageUrl).HasMaxLength(512); + b.Property(x => x.Category).IsRequired().HasMaxLength(64); + b.Property(x => x.PublishDate).IsRequired(); + b.Property(x => x.Attachments).HasMaxLength(2048); + b.Property(x => x.ViewCount).HasDefaultValue(0); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.Survey)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.Title).IsRequired().HasMaxLength(256); + b.Property(x => x.Description).HasMaxLength(2048); + b.Property(x => x.Deadline).IsRequired(); + b.Property(x => x.Responses).HasDefaultValue(0); + b.Property(x => x.Status).IsRequired().HasMaxLength(10); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SurveyQuestion)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.QuestionText).IsRequired().HasMaxLength(1024); + b.Property(x => x.Type).IsRequired().HasMaxLength(64); + + b.HasOne(x => x.Survey) + .WithMany(x => x.Questions) + .HasForeignKey(x => x.SurveyId) + .OnDelete(DeleteBehavior.Cascade); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SurveyQuestionOption)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.Text).IsRequired().HasMaxLength(512); + b.Property(x => x.Order).IsRequired(); + + b.HasOne(x => x.Question) + .WithMany(x => x.Options) + .HasForeignKey(x => x.QuestionId) + .OnDelete(DeleteBehavior.Cascade); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SurveyResponse)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.SubmissionTime).IsRequired(); + + b.HasOne(x => x.Survey) + .WithMany(x => x.SurveyResponses) + .HasForeignKey(x => x.SurveyId) + .OnDelete(DeleteBehavior.Cascade); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SurveyAnswer)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.QuestionType).IsRequired().HasMaxLength(64); + b.Property(x => x.Value).IsRequired().HasMaxLength(1024); + + b.HasOne(x => x.Response) + .WithMany(x => x.Answers) + .HasForeignKey(x => x.ResponseId) + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne(x => x.Question) + .WithMany() + .HasForeignKey(x => x.QuestionId) + .OnDelete(DeleteBehavior.Restrict); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialPost)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.Content).IsRequired().HasMaxLength(4096); + b.Property(x => x.LikeCount).HasDefaultValue(0); + b.Property(x => x.IsOwnPost).HasDefaultValue(false); + b.Property(x => x.IsLiked).HasDefaultValue(false); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialLocation)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.Name).IsRequired().HasMaxLength(256); + b.Property(x => x.Address).HasMaxLength(512); + b.Property(x => x.PlaceId).HasMaxLength(128); + + b.HasOne(x => x.SocialPost) + .WithOne(p => p.Location) + .HasForeignKey(x => x.SocialPostId) + .OnDelete(DeleteBehavior.Cascade); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialMedia)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.Type).IsRequired().HasMaxLength(64); + b.Property(x => x.Urls).HasMaxLength(2048); + b.Property(x => x.PollQuestion).HasMaxLength(512); + b.Property(x => x.PollUserVoteId).HasMaxLength(128); + + b.HasOne(x => x.SocialPost) + .WithOne(p => p.Media) + .HasForeignKey(x => x.SocialPostId) + .OnDelete(DeleteBehavior.Cascade); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialPollOption)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.Text).IsRequired().HasMaxLength(512); + + b.HasOne(x => x.SocialMedia) + .WithMany(x => x.PollOptions) + .HasForeignKey(x => x.SocialMediaId) + .OnDelete(DeleteBehavior.Cascade); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialComment)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.Property(x => x.Content).IsRequired().HasMaxLength(8192); + + b.HasOne(x => x.SocialPost) + .WithMany(x => x.Comments) + .HasForeignKey(x => x.SocialPostId) + .OnDelete(DeleteBehavior.Cascade); + }); + + builder.Entity(b => + { + b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.SocialLike)), Prefix.DbSchema); + b.ConfigureByConvention(); + + b.HasOne(x => x.SocialPost) + .WithMany(x => x.Likes) + .HasForeignKey(x => x.SocialPostId) + .OnDelete(DeleteBehavior.Cascade); + }); } } diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505071050_Initial.Designer.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505120031_Initial.Designer.cs similarity index 87% rename from api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505071050_Initial.Designer.cs rename to api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505120031_Initial.Designer.cs index 5276f3c..c9f5311 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505071050_Initial.Designer.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505120031_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace Sozsoft.Platform.Migrations { [DbContext(typeof(PlatformDbContext))] - [Migration("20260505071050_Initial")] + [Migration("20260505120031_Initial")] partial class Initial { /// @@ -559,6 +559,95 @@ namespace Sozsoft.Platform.Migrations b.ToTable("Sas_H_AiBot", (string)null); }); + modelBuilder.Entity("Sozsoft.Platform.Entities.Announcement", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Attachments") + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Excerpt") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ExpiryDate") + .HasColumnType("datetime2"); + + b.Property("ImageUrl") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsPinned") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PublishDate") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ViewCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0); + + b.HasKey("Id"); + + b.ToTable("Adm_T_Announcement", (string)null); + }); + modelBuilder.Entity("Sozsoft.Platform.Entities.BackgroundWorker", b => { b.Property("Id") @@ -3757,6 +3846,691 @@ namespace Sozsoft.Platform.Migrations b.ToTable("Sas_H_SkillType", (string)null); }); + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialComment", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(8192) + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("SocialPostId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SocialPostId"); + + b.ToTable("Adm_T_SocialComment", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialLike", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("SocialPostId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SocialPostId"); + + b.ToTable("Adm_T_SocialLike", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialLocation", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Address") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Lat") + .HasColumnType("float"); + + b.Property("Lng") + .HasColumnType("float"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PlaceId") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SocialPostId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("SocialPostId") + .IsUnique(); + + b.ToTable("Adm_T_SocialLocation", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialMedia", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PollEndsAt") + .HasColumnType("datetime2"); + + b.Property("PollQuestion") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("PollTotalVotes") + .HasColumnType("int"); + + b.Property("PollUserVoteId") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SocialPostId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.PrimitiveCollection("Urls") + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("SocialPostId") + .IsUnique(); + + b.ToTable("Adm_T_SocialMedia", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialPollOption", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("SocialMediaId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("Votes") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("SocialMediaId"); + + b.ToTable("Adm_T_SocialPollOption", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialPost", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsLiked") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("IsOwnPost") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LikeCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("Adm_T_SocialPost", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.Survey", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Deadline") + .HasColumnType("datetime2"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.Property("IsAnonymous") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Responses") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0); + + b.Property("Status") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.ToTable("Adm_T_Survey", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyAnswer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("QuestionId") + .HasColumnType("uniqueidentifier"); + + b.Property("QuestionType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ResponseId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("Id"); + + b.HasIndex("QuestionId"); + + b.HasIndex("ResponseId"); + + b.ToTable("Adm_T_SurveyAnswer", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyQuestion", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsRequired") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("QuestionText") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("SurveyId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.ToTable("Adm_T_SurveyQuestion", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyQuestionOption", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("QuestionId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.HasKey("Id"); + + b.HasIndex("QuestionId"); + + b.ToTable("Adm_T_SurveyQuestionOption", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyResponse", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("SubmissionTime") + .HasColumnType("datetime2"); + + b.Property("SurveyId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.ToTable("Adm_T_SurveyResponse", (string)null); + }); + modelBuilder.Entity("Sozsoft.Platform.Entities.Uom", b => { b.Property("Id") @@ -6429,6 +7203,113 @@ namespace Sozsoft.Platform.Migrations b.Navigation("SkillType"); }); + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialComment", b => + { + b.HasOne("Sozsoft.Platform.Entities.SocialPost", "SocialPost") + .WithMany("Comments") + .HasForeignKey("SocialPostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SocialPost"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialLike", b => + { + b.HasOne("Sozsoft.Platform.Entities.SocialPost", "SocialPost") + .WithMany("Likes") + .HasForeignKey("SocialPostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SocialPost"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialLocation", b => + { + b.HasOne("Sozsoft.Platform.Entities.SocialPost", "SocialPost") + .WithOne("Location") + .HasForeignKey("Sozsoft.Platform.Entities.SocialLocation", "SocialPostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SocialPost"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialMedia", b => + { + b.HasOne("Sozsoft.Platform.Entities.SocialPost", "SocialPost") + .WithOne("Media") + .HasForeignKey("Sozsoft.Platform.Entities.SocialMedia", "SocialPostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SocialPost"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialPollOption", b => + { + b.HasOne("Sozsoft.Platform.Entities.SocialMedia", "SocialMedia") + .WithMany("PollOptions") + .HasForeignKey("SocialMediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SocialMedia"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyAnswer", b => + { + b.HasOne("Sozsoft.Platform.Entities.SurveyQuestion", "Question") + .WithMany() + .HasForeignKey("QuestionId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Sozsoft.Platform.Entities.SurveyResponse", "Response") + .WithMany("Answers") + .HasForeignKey("ResponseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Question"); + + b.Navigation("Response"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyQuestion", b => + { + b.HasOne("Sozsoft.Platform.Entities.Survey", "Survey") + .WithMany("Questions") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Survey"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyQuestionOption", b => + { + b.HasOne("Sozsoft.Platform.Entities.SurveyQuestion", "Question") + .WithMany("Options") + .HasForeignKey("QuestionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Question"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyResponse", b => + { + b.HasOne("Sozsoft.Platform.Entities.Survey", "Survey") + .WithMany("SurveyResponses") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Survey"); + }); + modelBuilder.Entity("Sozsoft.Platform.Entities.Uom", b => { b.HasOne("Sozsoft.Platform.Entities.UomCategory", "UomCategory") @@ -6673,6 +7554,39 @@ namespace Sozsoft.Platform.Migrations b.Navigation("Skills"); }); + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialMedia", b => + { + b.Navigation("PollOptions"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialPost", b => + { + b.Navigation("Comments"); + + b.Navigation("Likes"); + + b.Navigation("Location"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.Survey", b => + { + b.Navigation("Questions"); + + b.Navigation("SurveyResponses"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyQuestion", b => + { + b.Navigation("Options"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyResponse", b => + { + b.Navigation("Answers"); + }); + modelBuilder.Entity("Sozsoft.Platform.Entities.UomCategory", b => { b.Navigation("Uoms"); diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505071050_Initial.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505120031_Initial.cs similarity index 88% rename from api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505071050_Initial.cs rename to api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505120031_Initial.cs index 87f83b4..d0866c1 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505071050_Initial.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260505120031_Initial.cs @@ -462,6 +462,36 @@ namespace Sozsoft.Platform.Migrations table.PrimaryKey("PK_AbpUsers", x => x.Id); }); + migrationBuilder.CreateTable( + name: "Adm_T_Announcement", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Title = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Excerpt = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: false), + Content = table.Column(type: "nvarchar(max)", maxLength: 4096, nullable: false), + ImageUrl = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + Category = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + UserId = table.Column(type: "uniqueidentifier", nullable: true), + PublishDate = table.Column(type: "datetime2", nullable: false), + ExpiryDate = table.Column(type: "datetime2", nullable: true), + IsPinned = table.Column(type: "bit", nullable: false), + ViewCount = table.Column(type: "int", nullable: false, defaultValue: 0), + Attachments = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_Announcement", x => x.Id); + }); + migrationBuilder.CreateTable( name: "Adm_T_Department", columns: table => new @@ -572,6 +602,55 @@ namespace Sozsoft.Platform.Migrations table.PrimaryKey("PK_Adm_T_Sector", x => x.Id); }); + migrationBuilder.CreateTable( + name: "Adm_T_SocialPost", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + UserId = table.Column(type: "uniqueidentifier", nullable: true), + Content = table.Column(type: "nvarchar(max)", maxLength: 4096, nullable: false), + LikeCount = table.Column(type: "int", nullable: false, defaultValue: 0), + IsLiked = table.Column(type: "bit", nullable: false, defaultValue: false), + IsOwnPost = table.Column(type: "bit", nullable: false, defaultValue: false), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_SocialPost", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Adm_T_Survey", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Title = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Description = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: true), + Deadline = table.Column(type: "datetime2", nullable: false), + Responses = table.Column(type: "int", nullable: false, defaultValue: 0), + Status = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: false), + IsAnonymous = table.Column(type: "bit", nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_Survey", x => x.Id); + }); + migrationBuilder.CreateTable( name: "Adm_T_WorkHour", columns: table => new @@ -1867,6 +1946,182 @@ namespace Sozsoft.Platform.Migrations onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateTable( + name: "Adm_T_SocialComment", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + SocialPostId = table.Column(type: "uniqueidentifier", nullable: false), + UserId = table.Column(type: "uniqueidentifier", nullable: true), + Content = table.Column(type: "nvarchar(max)", maxLength: 8192, nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_SocialComment", x => x.Id); + table.ForeignKey( + name: "FK_Adm_T_SocialComment_Adm_T_SocialPost_SocialPostId", + column: x => x.SocialPostId, + principalTable: "Adm_T_SocialPost", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Adm_T_SocialLike", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + SocialPostId = table.Column(type: "uniqueidentifier", nullable: false), + UserId = table.Column(type: "uniqueidentifier", nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_SocialLike", x => x.Id); + table.ForeignKey( + name: "FK_Adm_T_SocialLike_Adm_T_SocialPost_SocialPostId", + column: x => x.SocialPostId, + principalTable: "Adm_T_SocialPost", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Adm_T_SocialLocation", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + SocialPostId = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Address = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + Lat = table.Column(type: "float", nullable: true), + Lng = table.Column(type: "float", nullable: true), + PlaceId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_SocialLocation", x => x.Id); + table.ForeignKey( + name: "FK_Adm_T_SocialLocation_Adm_T_SocialPost_SocialPostId", + column: x => x.SocialPostId, + principalTable: "Adm_T_SocialPost", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Adm_T_SocialMedia", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + SocialPostId = table.Column(type: "uniqueidentifier", nullable: false), + Type = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Urls = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: true), + PollQuestion = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + PollTotalVotes = table.Column(type: "int", nullable: true), + PollEndsAt = table.Column(type: "datetime2", nullable: true), + PollUserVoteId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_SocialMedia", x => x.Id); + table.ForeignKey( + name: "FK_Adm_T_SocialMedia_Adm_T_SocialPost_SocialPostId", + column: x => x.SocialPostId, + principalTable: "Adm_T_SocialPost", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Adm_T_SurveyQuestion", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + SurveyId = table.Column(type: "uniqueidentifier", nullable: false), + QuestionText = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false), + Type = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Order = table.Column(type: "int", nullable: false), + IsRequired = table.Column(type: "bit", nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_SurveyQuestion", x => x.Id); + table.ForeignKey( + name: "FK_Adm_T_SurveyQuestion_Adm_T_Survey_SurveyId", + column: x => x.SurveyId, + principalTable: "Adm_T_Survey", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Adm_T_SurveyResponse", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + SurveyId = table.Column(type: "uniqueidentifier", nullable: false), + UserId = table.Column(type: "uniqueidentifier", nullable: true), + SubmissionTime = table.Column(type: "datetime2", nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_SurveyResponse", x => x.Id); + table.ForeignKey( + name: "FK_Adm_T_SurveyResponse_Adm_T_Survey_SurveyId", + column: x => x.SurveyId, + principalTable: "Adm_T_Survey", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + migrationBuilder.CreateTable( name: "OpenIddictAuthorizations", columns: table => new @@ -2365,6 +2620,97 @@ namespace Sozsoft.Platform.Migrations onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateTable( + name: "Adm_T_SocialPollOption", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + SocialMediaId = table.Column(type: "uniqueidentifier", nullable: false), + Text = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: false), + Votes = table.Column(type: "int", nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_SocialPollOption", x => x.Id); + table.ForeignKey( + name: "FK_Adm_T_SocialPollOption_Adm_T_SocialMedia_SocialMediaId", + column: x => x.SocialMediaId, + principalTable: "Adm_T_SocialMedia", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Adm_T_SurveyQuestionOption", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + QuestionId = table.Column(type: "uniqueidentifier", nullable: false), + Text = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: false), + Order = table.Column(type: "int", nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_SurveyQuestionOption", x => x.Id); + table.ForeignKey( + name: "FK_Adm_T_SurveyQuestionOption_Adm_T_SurveyQuestion_QuestionId", + column: x => x.QuestionId, + principalTable: "Adm_T_SurveyQuestion", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Adm_T_SurveyAnswer", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + ResponseId = table.Column(type: "uniqueidentifier", nullable: false), + QuestionId = table.Column(type: "uniqueidentifier", nullable: false), + QuestionType = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Value = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Adm_T_SurveyAnswer", x => x.Id); + table.ForeignKey( + name: "FK_Adm_T_SurveyAnswer_Adm_T_SurveyQuestion_QuestionId", + column: x => x.QuestionId, + principalTable: "Adm_T_SurveyQuestion", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Adm_T_SurveyAnswer_Adm_T_SurveyResponse_ResponseId", + column: x => x.ResponseId, + principalTable: "Adm_T_SurveyResponse", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + migrationBuilder.CreateTable( name: "OpenIddictTokens", columns: table => new @@ -2781,6 +3127,58 @@ namespace Sozsoft.Platform.Migrations table: "Adm_T_ReportTemplate", column: "CategoryId"); + migrationBuilder.CreateIndex( + name: "IX_Adm_T_SocialComment_SocialPostId", + table: "Adm_T_SocialComment", + column: "SocialPostId"); + + migrationBuilder.CreateIndex( + name: "IX_Adm_T_SocialLike_SocialPostId", + table: "Adm_T_SocialLike", + column: "SocialPostId"); + + migrationBuilder.CreateIndex( + name: "IX_Adm_T_SocialLocation_SocialPostId", + table: "Adm_T_SocialLocation", + column: "SocialPostId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Adm_T_SocialMedia_SocialPostId", + table: "Adm_T_SocialMedia", + column: "SocialPostId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Adm_T_SocialPollOption_SocialMediaId", + table: "Adm_T_SocialPollOption", + column: "SocialMediaId"); + + migrationBuilder.CreateIndex( + name: "IX_Adm_T_SurveyAnswer_QuestionId", + table: "Adm_T_SurveyAnswer", + column: "QuestionId"); + + migrationBuilder.CreateIndex( + name: "IX_Adm_T_SurveyAnswer_ResponseId", + table: "Adm_T_SurveyAnswer", + column: "ResponseId"); + + migrationBuilder.CreateIndex( + name: "IX_Adm_T_SurveyQuestion_SurveyId", + table: "Adm_T_SurveyQuestion", + column: "SurveyId"); + + migrationBuilder.CreateIndex( + name: "IX_Adm_T_SurveyQuestionOption_QuestionId", + table: "Adm_T_SurveyQuestionOption", + column: "QuestionId"); + + migrationBuilder.CreateIndex( + name: "IX_Adm_T_SurveyResponse_SurveyId", + table: "Adm_T_SurveyResponse", + column: "SurveyId"); + migrationBuilder.CreateIndex( name: "IX_OpenIddictApplications_ClientId", table: "OpenIddictApplications", @@ -3065,6 +3463,9 @@ namespace Sozsoft.Platform.Migrations migrationBuilder.DropTable( name: "AbpUserTokens"); + migrationBuilder.DropTable( + name: "Adm_T_Announcement"); + migrationBuilder.DropTable( name: "Adm_T_IpRestriction"); @@ -3080,6 +3481,24 @@ namespace Sozsoft.Platform.Migrations migrationBuilder.DropTable( name: "Adm_T_Sector"); + migrationBuilder.DropTable( + name: "Adm_T_SocialComment"); + + migrationBuilder.DropTable( + name: "Adm_T_SocialLike"); + + migrationBuilder.DropTable( + name: "Adm_T_SocialLocation"); + + migrationBuilder.DropTable( + name: "Adm_T_SocialPollOption"); + + migrationBuilder.DropTable( + name: "Adm_T_SurveyAnswer"); + + migrationBuilder.DropTable( + name: "Adm_T_SurveyQuestionOption"); + migrationBuilder.DropTable( name: "Adm_T_WorkHour"); @@ -3221,6 +3640,15 @@ namespace Sozsoft.Platform.Migrations migrationBuilder.DropTable( name: "Adm_T_ReportCategory"); + migrationBuilder.DropTable( + name: "Adm_T_SocialMedia"); + + migrationBuilder.DropTable( + name: "Adm_T_SurveyResponse"); + + migrationBuilder.DropTable( + name: "Adm_T_SurveyQuestion"); + migrationBuilder.DropTable( name: "OpenIddictAuthorizations"); @@ -3263,6 +3691,12 @@ namespace Sozsoft.Platform.Migrations migrationBuilder.DropTable( name: "AbpAuditLogs"); + migrationBuilder.DropTable( + name: "Adm_T_SocialPost"); + + migrationBuilder.DropTable( + name: "Adm_T_Survey"); + migrationBuilder.DropTable( name: "OpenIddictApplications"); diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs index eb5b672..82b0bb4 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs @@ -556,6 +556,95 @@ namespace Sozsoft.Platform.Migrations b.ToTable("Sas_H_AiBot", (string)null); }); + modelBuilder.Entity("Sozsoft.Platform.Entities.Announcement", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Attachments") + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Excerpt") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ExpiryDate") + .HasColumnType("datetime2"); + + b.Property("ImageUrl") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsPinned") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PublishDate") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ViewCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0); + + b.HasKey("Id"); + + b.ToTable("Adm_T_Announcement", (string)null); + }); + modelBuilder.Entity("Sozsoft.Platform.Entities.BackgroundWorker", b => { b.Property("Id") @@ -3754,6 +3843,691 @@ namespace Sozsoft.Platform.Migrations b.ToTable("Sas_H_SkillType", (string)null); }); + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialComment", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(8192) + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("SocialPostId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SocialPostId"); + + b.ToTable("Adm_T_SocialComment", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialLike", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("SocialPostId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SocialPostId"); + + b.ToTable("Adm_T_SocialLike", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialLocation", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Address") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Lat") + .HasColumnType("float"); + + b.Property("Lng") + .HasColumnType("float"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PlaceId") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SocialPostId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("SocialPostId") + .IsUnique(); + + b.ToTable("Adm_T_SocialLocation", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialMedia", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PollEndsAt") + .HasColumnType("datetime2"); + + b.Property("PollQuestion") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("PollTotalVotes") + .HasColumnType("int"); + + b.Property("PollUserVoteId") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SocialPostId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.PrimitiveCollection("Urls") + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("SocialPostId") + .IsUnique(); + + b.ToTable("Adm_T_SocialMedia", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialPollOption", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("SocialMediaId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("Votes") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("SocialMediaId"); + + b.ToTable("Adm_T_SocialPollOption", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialPost", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(4096) + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsLiked") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("IsOwnPost") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LikeCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("Adm_T_SocialPost", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.Survey", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Deadline") + .HasColumnType("datetime2"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.Property("IsAnonymous") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Responses") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0); + + b.Property("Status") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.ToTable("Adm_T_Survey", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyAnswer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("QuestionId") + .HasColumnType("uniqueidentifier"); + + b.Property("QuestionType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ResponseId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("Id"); + + b.HasIndex("QuestionId"); + + b.HasIndex("ResponseId"); + + b.ToTable("Adm_T_SurveyAnswer", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyQuestion", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsRequired") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("QuestionText") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("SurveyId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.ToTable("Adm_T_SurveyQuestion", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyQuestionOption", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("QuestionId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.HasKey("Id"); + + b.HasIndex("QuestionId"); + + b.ToTable("Adm_T_SurveyQuestionOption", (string)null); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyResponse", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("SubmissionTime") + .HasColumnType("datetime2"); + + b.Property("SurveyId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.ToTable("Adm_T_SurveyResponse", (string)null); + }); + modelBuilder.Entity("Sozsoft.Platform.Entities.Uom", b => { b.Property("Id") @@ -6426,6 +7200,113 @@ namespace Sozsoft.Platform.Migrations b.Navigation("SkillType"); }); + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialComment", b => + { + b.HasOne("Sozsoft.Platform.Entities.SocialPost", "SocialPost") + .WithMany("Comments") + .HasForeignKey("SocialPostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SocialPost"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialLike", b => + { + b.HasOne("Sozsoft.Platform.Entities.SocialPost", "SocialPost") + .WithMany("Likes") + .HasForeignKey("SocialPostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SocialPost"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialLocation", b => + { + b.HasOne("Sozsoft.Platform.Entities.SocialPost", "SocialPost") + .WithOne("Location") + .HasForeignKey("Sozsoft.Platform.Entities.SocialLocation", "SocialPostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SocialPost"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialMedia", b => + { + b.HasOne("Sozsoft.Platform.Entities.SocialPost", "SocialPost") + .WithOne("Media") + .HasForeignKey("Sozsoft.Platform.Entities.SocialMedia", "SocialPostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SocialPost"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialPollOption", b => + { + b.HasOne("Sozsoft.Platform.Entities.SocialMedia", "SocialMedia") + .WithMany("PollOptions") + .HasForeignKey("SocialMediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SocialMedia"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyAnswer", b => + { + b.HasOne("Sozsoft.Platform.Entities.SurveyQuestion", "Question") + .WithMany() + .HasForeignKey("QuestionId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Sozsoft.Platform.Entities.SurveyResponse", "Response") + .WithMany("Answers") + .HasForeignKey("ResponseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Question"); + + b.Navigation("Response"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyQuestion", b => + { + b.HasOne("Sozsoft.Platform.Entities.Survey", "Survey") + .WithMany("Questions") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Survey"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyQuestionOption", b => + { + b.HasOne("Sozsoft.Platform.Entities.SurveyQuestion", "Question") + .WithMany("Options") + .HasForeignKey("QuestionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Question"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyResponse", b => + { + b.HasOne("Sozsoft.Platform.Entities.Survey", "Survey") + .WithMany("SurveyResponses") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Survey"); + }); + modelBuilder.Entity("Sozsoft.Platform.Entities.Uom", b => { b.HasOne("Sozsoft.Platform.Entities.UomCategory", "UomCategory") @@ -6670,6 +7551,39 @@ namespace Sozsoft.Platform.Migrations b.Navigation("Skills"); }); + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialMedia", b => + { + b.Navigation("PollOptions"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SocialPost", b => + { + b.Navigation("Comments"); + + b.Navigation("Likes"); + + b.Navigation("Location"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.Survey", b => + { + b.Navigation("Questions"); + + b.Navigation("SurveyResponses"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyQuestion", b => + { + b.Navigation("Options"); + }); + + modelBuilder.Entity("Sozsoft.Platform.Entities.SurveyResponse", b => + { + b.Navigation("Answers"); + }); + modelBuilder.Entity("Sozsoft.Platform.Entities.UomCategory", b => { b.Navigation("Uoms"); diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/TenantData.json b/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/TenantData.json index 8e23568..8a63afe 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/TenantData.json +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/TenantData.json @@ -1289,5 +1289,395 @@ "Name": "Muhasebe Şefi", "ParentName": "Muhasebe Müdürü" } + ], + "Announcements": [ + { + "title": "🎉 Yeni Ofis Açılışı", + "content": "Ankara ofisimiz 1 Kasım tarihinde hizmete başlıyor! Tüm çalışanlarımızı açılış törenimize davet ediyoruz.", + "excerpt": "Ankara ofisimiz 1 Kasım tarihinde hizmete başlıyor!", + "category": "general", + "userName": "system@sozsoft.com", + "publishDate": "12-10-2024", + "isPinned": true, + "viewCount": 156, + "imageUrl": "https://images.unsplash.com/photo-1497366216548-37526070297c?w=800&q=80" + }, + { + "title": "📅 Performans Değerlendirme Dönemi", + "content": "Yıl sonu performans değerlendirmelerimiz 20 Ekim - 5 Kasım tarihleri arasında gerçekleştirilecektir. Lütfen formları zamanında doldurunuz.", + "excerpt": "Yıl sonu performans değerlendirmeleri başlıyor.", + "category": "hr", + "userName": "system@sozsoft.com", + "publishDate": "08-10-2024", + "expiryDate": "05-11-2024", + "isPinned": true, + "viewCount": 89 + }, + { + "title": "💻 Sistem Bakımı Duyurusu", + "content": "Bu Cumartesi saat 02: 00 - 06: 00 arası sistemlerimizde bakım çalışması yapılacaktır. Bu süre içinde sistemlere erişim sağlanamayacaktır.", + "excerpt": "Cumartesi gecesi planlı bakım çalışması", + "category": "it", + "userName": "system@sozsoft.com", + "publishDate": "08-10-2024", + "isPinned": false, + "viewCount": 234 + }, + { + "title": "🎓 React İleri Seviye Eğitimi", + "content": "Yazılım Geliştirme ekibimiz için React İleri Seviye eğitimi 25-26 Ekim tarihlerinde düzenlenecektir. Katılım için IK birimine başvurunuz.", + "excerpt": "React İleri Seviye eğitimi kayıtları başladı", + "category": "event", + "userName": "system@sozsoft.com", + "publishDate": "09-10-2024", + "isPinned": false, + "viewCount": 67 + }, + { + "title": "⚠️ Güvenlik Politikası Güncellemesi", + "content": "Bilgi güvenliği politikamız güncellenmiştir. Tüm çalışanlarımızın yeni politikayı okuması ve onaylaması gerekmektedir.", + "excerpt": "Güvenlik politikası güncellendi - Onay gerekli", + "category": "urgent", + "userName": "system@sozsoft.com", + "publishDate": "04-10-2024", + "isPinned": true, + "viewCount": 312 + } + ], + "Surveys": [ + { + "Title": "Çalışan Memnuniyet Anketi 2024", + "Description": "Yıllık çalışan memnuniyeti ve bağlılık araştırması", + "Deadline": "2024-10-31T00:00:00", + "Responses": 45, + "Status": "active", + "IsAnonymous": true + }, + { + "Title": "Eğitim İhtiyaç Analizi", + "Description": "2025 yılı eğitim planlaması için ihtiyaç tespiti", + "Deadline": "2024-11-15T00:00:00", + "Responses": 28, + "Status": "active", + "IsAnonymous": false + }, + { + "Title": "Kafeterya Memnuniyet Anketi", + "Description": "Yemek kalitesi ve servis değerlendirmesi", + "Deadline": "2024-09-30T00:00:00", + "Responses": 62, + "Status": "passive", + "IsAnonymous": true + } + ], + "SurveyQuestions": [ + { + "SurveyTitle": "Çalışan Memnuniyet Anketi 2024", + "QuestionText": "Genel memnuniyet düzeyiniz nedir?", + "Type": "rating", + "Order": 1, + "IsRequired": true + }, + { + "SurveyTitle": "Çalışan Memnuniyet Anketi 2024", + "QuestionText": "Hangi departmanda çalışıyorsunuz?", + "Type": "multiple-choice", + "Order": 2, + "IsRequired": true + }, + { + "SurveyTitle": "Çalışan Memnuniyet Anketi 2024", + "QuestionText": "Görüş ve önerileriniz", + "Type": "textarea", + "Order": 3, + "IsRequired": false + }, + { + "SurveyTitle": "Çalışan Memnuniyet Anketi 2024", + "QuestionText": "Çalışma ortamından memnun musunuz?", + "Type": "yes-no", + "Order": 4, + "IsRequired": true + }, + { + "SurveyTitle": "Eğitim İhtiyaç Analizi", + "QuestionText": "Hangi teknoloji konularında eğitim almak istiyorsunuz?", + "Type": "multiple-choice", + "Order": 1, + "IsRequired": true + }, + { + "SurveyTitle": "Eğitim İhtiyaç Analizi", + "QuestionText": "Eğitim formatı tercihiniz nedir?", + "Type": "multiple-choice", + "Order": 2, + "IsRequired": true + }, + { + "SurveyTitle": "Eğitim İhtiyaç Analizi", + "QuestionText": "Eğitim için haftalık ne kadar zaman ayırabilirsiniz?", + "Type": "rating", + "Order": 3, + "IsRequired": true + }, + { + "SurveyTitle": "Kafeterya Memnuniyet Anketi", + "QuestionText": "Yemek kalitesini nasıl değerlendiriyorsunuz?", + "Type": "rating", + "Order": 1, + "IsRequired": true + }, + { + "SurveyTitle": "Kafeterya Memnuniyet Anketi", + "QuestionText": "Hangi yemekleri daha sık görmek istiyorsunuz?", + "Type": "textarea", + "Order": 2, + "IsRequired": false + }, + { + "SurveyTitle": "Kafeterya Memnuniyet Anketi", + "QuestionText": "Servis hızından memnun musunuz?", + "Type": "yes-no", + "Order": 3, + "IsRequired": true + } + ], + "SurveyQuestionOptions": [ + { + "QuestionText": "Hangi departmanda çalışıyorsunuz?", + "Text": "Bilgi Teknolojileri", + "Order": 1 + }, + { + "QuestionText": "Hangi departmanda çalışıyorsunuz?", + "Text": "İnsan Kaynakları", + "Order": 2 + }, + { + "QuestionText": "Hangi departmanda çalışıyorsunuz?", + "Text": "Finans", + "Order": 3 + }, + { + "QuestionText": "Hangi departmanda çalışıyorsunuz?", + "Text": "Satış", + "Order": 4 + }, + { + "QuestionText": "Hangi departmanda çalışıyorsunuz?", + "Text": "Pazarlama", + "Order": 5 + }, + { + "QuestionText": "Hangi teknoloji konularında eğitim almak istiyorsunuz?", + "Text": "React / Frontend", + "Order": 1 + }, + { + "QuestionText": "Hangi teknoloji konularında eğitim almak istiyorsunuz?", + "Text": "Node.js / Backend", + "Order": 2 + }, + { + "QuestionText": "Hangi teknoloji konularında eğitim almak istiyorsunuz?", + "Text": "Database / SQL", + "Order": 3 + }, + { + "QuestionText": "Hangi teknoloji konularında eğitim almak istiyorsunuz?", + "Text": "DevOps / Cloud", + "Order": 4 + }, + { + "QuestionText": "Hangi teknoloji konularında eğitim almak istiyorsunuz?", + "Text": "Mobile Development", + "Order": 5 + }, + { + "QuestionText": "Eğitim formatı tercihiniz nedir?", + "Text": "Online Eğitim", + "Order": 1 + }, + { + "QuestionText": "Eğitim formatı tercihiniz nedir?", + "Text": "Yüz Yüze Eğitim", + "Order": 2 + }, + { + "QuestionText": "Eğitim formatı tercihiniz nedir?", + "Text": "Hibrit (Karma)", + "Order": 3 + } + ], + "SocialPosts": [ + { + "content": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀", + "userName": "system@sozsoft.com", + "likeCount": 24, + "isLiked": true, + "isOwnPost": false + }, + { + "content": "Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!", + "userName": "system@sozsoft.com", + "likeCount": 18, + "isLiked": false, + "isOwnPost": true + }, + { + "content": "Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨", + "userName": "system@sozsoft.com", + "likeCount": 42, + "isLiked": true, + "isOwnPost": false + }, + { + "content": "CI/CD pipeline güncellememiz tamamlandı! Deployment süremiz %40 azaldı. Otomasyonun gücü 💪", + "userName": "system@sozsoft.com", + "likeCount": 31, + "isLiked": false, + "isOwnPost": false + }, + { + "content": "Ekip üyelerimize yeni eğitim programımızı duyurmak istiyorum! 🎓 React, TypeScript ve Modern Web Geliştirme konularında kapsamlı bir program hazırladık.", + "userName": "system@sozsoft.com", + "likeCount": 56, + "isLiked": true, + "isOwnPost": false + }, + { + "content": "Bugün müşteri ile harika bir toplantı yaptık! Yeni projenin detaylarını konuştuk. 🎯", + "userName": "system@sozsoft.com", + "likeCount": 18, + "isLiked": false, + "isOwnPost": false + } + ], + "SocialLocations": [ + { + "postContent": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀", + "name": "Taksim Meydanı", + "address": "Taksim, Gümüşsuyu Mahallesi, 34437 Beyoğlu/İstanbul", + "lat": 41.0369, + "lng": 28.985, + "placeId": "ChIJBQRGmL25yhQRXwqRTHAwAAQ" + }, + { + "postContent": "Bugün müşteri ile harika bir toplantı yaptık! Yeni projenin detaylarını konuştuk. 🎯", + "name": "Sultanahmet Meydanı", + "address": "Sultanahmet Mahallesi, 34122 Fatih/İstanbul", + "lat": 41.0058, + "lng": 28.9768, + "placeId": "ChIJ7fVVZiy5yhQRzsXXXXXXXXk" + } + ], + "SocialMedias": [ + { + "postContent": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀", + "type": "image", + "urls": [ + "https://images.unsplash.com/photo-1633356122544-f134324a6cee?w=800&q=80" + ] + }, + { + "postContent": "Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!", + "type": "poll", + "pollQuestion": "Hangi özelliği öncelikli olarak geliştirmeliyiz?", + "pollTotalVotes": 40, + "pollEndsAt": "2024-10-20T23:59:59", + "pollUserVoteId": "p3" + }, + { + "postContent": "Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨", + "type": "image", + "urls": [ + "https://images.unsplash.com/photo-1561070791-2526d30994b5?w=800&q=80", + "https://images.unsplash.com/photo-1586717799252-bd134ad00e26?w=800&q=80", + "https://images.unsplash.com/photo-1609921212029-bb5a28e60960?w=800&q=80" + ] + }, + { + "postContent": "CI/CD pipeline güncellememiz tamamlandı! Deployment süremiz %40 azaldı. Otomasyonun gücü 💪", + "type": "video", + "urls": ["https://www.w3schools.com/html/mov_bbb.mp4"] + } + ], + "SocialPollOptions": [ + { + "postContent": "Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!", + "pollQuestion": "Hangi özelliği öncelikli olarak geliştirmeliyiz?", + "Text": "Kullanıcı profilleri", + "Votes": 12 + }, + { + "postContent": "Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!", + "pollQuestion": "Hangi özelliği öncelikli olarak geliştirmeliyiz?", + "Text": "Bildirim sistemi", + "Votes": 8 + }, + { + "postContent": "Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!", + "pollQuestion": "Hangi özelliği öncelikli olarak geliştirmeliyiz?", + "Text": "Mesajlaşma", + "Votes": 15 + }, + { + "postContent": "Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!", + "pollQuestion": "Hangi özelliği öncelikli olarak geliştirmeliyiz?", + "Text": "Raporlama", + "Votes": 5 + } + ], + "SocialComments": [ + { + "postContent": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀", + "userName": "system@sozsoft.com", + "content": "Harika görünüyor! Başarılar 👏" + }, + { + "postContent": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀", + "userName": "system@sozsoft.com", + "content": "TypeScript gerçekten fark yaratıyor!" + }, + { + "postContent": "Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!", + "userName": "system@sozsoft.com", + "content": "Mesajlaşma özelliğine kesinlikle ihtiyacımız var!" + }, + { + "postContent": "Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨", + "userName": "system@sozsoft.com", + "content": "Tasarımlar çok şık! Renk paleti özellikle güzel 😍" + }, + { + "postContent": "Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨", + "userName": "system@sozsoft.com", + "content": "Dark mode opsiyonu da olacak mı?" + }, + { + "postContent": "CI/CD pipeline güncellememiz tamamlandı! Deployment süremiz %40 azaldı. Otomasyonun gücü 💪", + "userName": "system@sozsoft.com", + "content": "Harika iş! Detayları paylaşabilir misin?" + }, + { + "postContent": "Ekip üyelerimize yeni eğitim programımızı duyurmak istiyorum! 🎓 React, TypeScript ve Modern Web Geliştirme konularında kapsamlı bir program hazırladık.", + "userName": "system@sozsoft.com", + "content": "Ne zaman başlıyor?" + }, + { + "postContent": "Ekip üyelerimize yeni eğitim programımızı duyurmak istiyorum! 🎓 React, TypeScript ve Modern Web Geliştirme konularında kapsamlı bir program hazırladık.", + "userName": "system@sozsoft.com", + "content": "Gelecek hafta başlıyoruz! Kayıt linki mail ile paylaşılacak." + } + ], + "SocialLikes": [ + { + "postContent": "Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀", + "userName": "system@sozsoft.com" + }, + { + "postContent": "Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨", + "userName": "system@sozsoft.com" + } ] } diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/TenantDataSeeder.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/TenantDataSeeder.cs index bd85378..5e8d0e7 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/TenantDataSeeder.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/TenantDataSeeder.cs @@ -15,6 +15,7 @@ using Volo.Abp.Timing; using System.Collections.Generic; using Volo.Abp.MultiTenancy; using Sozsoft.Platform.Extensions; +using System.Linq; namespace Sozsoft.Platform.Data.Seeds; @@ -52,6 +53,113 @@ public class TenantSeederDto //Forum public List ForumCategories { get; set; } + + //Intranet + public List Announcements { get; set; } + public List Surveys { get; set; } + public List SurveyQuestions { get; set; } + public List SurveyQuestionOptions { get; set; } + public List SocialPosts { get; set; } + public List SocialLocations { get; set; } + public List SocialMedias { get; set; } + public List SocialPollOptions { get; set; } + public List SocialComments { get; set; } + public List SocialLikes { get; set; } +} + +public class SocialPostSeedDto +{ + public string Content { get; set; } + public string UserName { get; set; } + public int LikeCount { get; set; } + public bool IsLiked { get; set; } + public bool IsOwnPost { get; set; } +} + +public class SocialLocationSeedDto +{ + public string PostContent { get; set; } + public string Name { get; set; } + public string Address { get; set; } + public double? Lat { get; set; } + public double? Lng { get; set; } + public string PlaceId { get; set; } +} + +public class SocialMediaSeedDto +{ + public string PostContent { get; set; } + public string Type { get; set; } + public string[] Urls { get; set; } + + public string PollQuestion { get; set; } + public int? PollTotalVotes { get; set; } + public DateTime? PollEndsAt { get; set; } + public string PollUserVoteId { get; set; } + + public List PollOptions { get; set; } +} + +public class SocialPollOptionSeedDto +{ + public string PostContent { get; set; } + public string PollQuestion { get; set; } + public string Text { get; set; } + public int Votes { get; set; } +} + +public class SocialCommentSeedDto +{ + public string PostContent { get; set; } + public string UserName { get; set; } + public string Content { get; set; } +} + +public class SocialLikeSeedDto +{ + public string PostContent { get; set; } + public string UserName { get; set; } +} + +public class SurveySeedDto +{ + public string Title { get; set; } + public string Description { get; set; } + public DateTime Deadline { get; set; } + public int Responses { get; set; } + public string Status { get; set; } + public bool IsAnonymous { get; set; } +} + +public class SurveyQuestionSeedDto +{ + public string QuestionText { get; set; } + public string SurveyTitle { get; set; } + public string Type { get; set; } + public int Order { get; set; } + public bool IsRequired { get; set; } +} + +public class SurveyQuestionOptionSeedDto +{ + public string QuestionText { get; set; } + public string Text { get; set; } + public int Order { get; set; } +} + +public class AnnouncementSeedDto +{ + public string Title { get; set; } + public string Excerpt { get; set; } + public string Content { get; set; } + public string ImageUrl { get; set; } + public string Category { get; set; } + public string UserName { get; set; } + public DateTime PublishDate { get; set; } + public DateTime? ExpiryDate { get; set; } + public bool IsPinned { get; set; } + public int ViewCount { get; set; } + public string DepartmentNames { get; set; } } public class JobPositionSeedDto @@ -291,6 +399,16 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency private readonly IRepository _productRepository; private readonly IRepository _departmentRepository; private readonly IRepository _jobPositionRepository; + private readonly IRepository _announcementRepository; + private readonly IRepository _surveyRepository; + private readonly IRepository _surveyQuestionRepository; + private readonly IRepository _surveyQuestionOptionRepository; + private readonly IRepository _socialPostRepository; + private readonly IRepository _socialLocationRepository; + private readonly IRepository _socialMediaRepository; + private readonly IRepository _socialPollOptionRepository; + private readonly IRepository _socialCommentRepository; + private readonly IRepository _socialLikeRepository; private readonly ICurrentTenant _currentTenant; public TenantDataSeeder( @@ -322,6 +440,18 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency IRepository organizationUnitRepository, IRepository departmentRepository, IRepository jobPositionRepository, + + IRepository announcementRepository, + IRepository surveyRepository, + IRepository surveyQuestionRepository, + IRepository surveyQuestionOptionRepository, + IRepository socialPostRepository, + IRepository socialLocationRepository, + IRepository socialMediaRepository, + IRepository socialPollOptionRepository, + IRepository socialCommentRepository, + IRepository socialLikeRepository, + OrganizationUnitManager organizationUnitManager, ICurrentTenant currentTenant ) @@ -354,6 +484,16 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency _organizationUnitRepository = organizationUnitRepository; _departmentRepository = departmentRepository; _jobPositionRepository = jobPositionRepository; + _announcementRepository = announcementRepository; + _surveyRepository = surveyRepository; + _surveyQuestionRepository = surveyQuestionRepository; + _surveyQuestionOptionRepository = surveyQuestionOptionRepository; + _socialPostRepository = socialPostRepository; + _socialLocationRepository = socialLocationRepository; + _socialMediaRepository = socialMediaRepository; + _socialPollOptionRepository = socialPollOptionRepository; + _socialCommentRepository = socialCommentRepository; + _socialLikeRepository = socialLikeRepository; _organizationUnitManager = organizationUnitManager; _currentTenant = currentTenant; } @@ -770,6 +910,204 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency }, autoSave: true); } + foreach (var item in items.Announcements) + { + var exists = await _announcementRepository.AnyAsync(x => x.Title == item.Title); + if (exists) + continue; + + var user = await _repositoryUser.FindByNormalizedUserNameAsync(item.UserName); + await _announcementRepository.InsertAsync(new Announcement + { + Title = item.Title, + Excerpt = item.Excerpt, + Content = item.Content, + ImageUrl = item.ImageUrl, + Category = item.Category, + UserId = user != null ? user.Id : null, + PublishDate = item.PublishDate, + ExpiryDate = item.ExpiryDate, + IsPinned = item.IsPinned, + ViewCount = item.ViewCount + }); + } + + foreach (var item in items.Surveys) + { + var exists = await _surveyRepository.AnyAsync(x => x.Title == item.Title); + if (exists) + continue; + + await _surveyRepository.InsertAsync(new Survey + { + Title = item.Title, + Description = item.Description, + Deadline = item.Deadline, + Responses = item.Responses, + Status = item.Status, + IsAnonymous = item.IsAnonymous + }, autoSave: true); + } + + foreach (var item in items.SurveyQuestions) + { + var exists = await _surveyQuestionRepository.AnyAsync(x => x.QuestionText == item.QuestionText); + if (exists) + continue; + + var survey = await _surveyRepository.FirstOrDefaultAsync(x => x.Title == item.SurveyTitle); + await _surveyQuestionRepository.InsertAsync(new SurveyQuestion + { + SurveyId = survey != null ? survey.Id : Guid.Empty, + QuestionText = item.QuestionText, + Type = item.Type, + Order = item.Order, + IsRequired = item.IsRequired + }, autoSave: true); + } + + foreach (var item in items.SurveyQuestionOptions) + { + var surveyQuestion = await _surveyQuestionRepository.FirstOrDefaultAsync(x => x.QuestionText == item.QuestionText); + if (surveyQuestion == null) + continue; + + var exists = await _surveyQuestionOptionRepository.AnyAsync(x => x.QuestionId == surveyQuestion.Id && x.Text == item.Text); + if (exists) + continue; + + await _surveyQuestionOptionRepository.InsertAsync(new SurveyQuestionOption + { + QuestionId = surveyQuestion.Id, + Text = item.Text, + Order = item.Order + }, autoSave: true); + } + + foreach (var item in items.SocialPosts) + { + var exists = await _socialPostRepository.AnyAsync(x => x.Content == item.Content); + if (exists) + continue; + + var user = await _repositoryUser.FindByNormalizedUserNameAsync(item.UserName); + + await _socialPostRepository.InsertAsync(new SocialPost + { + UserId = user != null ? user.Id : null, + Content = item.Content, + LikeCount = item.LikeCount, + IsLiked = item.IsLiked, + IsOwnPost = item.IsOwnPost + }, autoSave: true); + } + + foreach (var item in items.SocialLocations) + { + var post = await _socialPostRepository.FirstOrDefaultAsync(x => x.Content == item.PostContent); + + if (post == null) + continue; + + var exists = await _socialLocationRepository.AnyAsync(x => x.SocialPostId == post.Id && x.Name == item.Name); + if (exists) + continue; + + await _socialLocationRepository.InsertAsync(new SocialLocation + { + SocialPostId = post != null ? post.Id : Guid.Empty, + Name = item.Name, + Address = item.Address, + Lat = item.Lat, + Lng = item.Lng, + PlaceId = item.PlaceId + }, autoSave: true); + } + + foreach (var item in items.SocialMedias) + { + var post = await _socialPostRepository.FirstOrDefaultAsync(x => x.Content == item.PostContent); + + if (post == null) + continue; + + var exists = await _socialMediaRepository.AnyAsync(x => x.SocialPostId == post.Id); + if (exists) + continue; + + await _socialMediaRepository.InsertAsync(new SocialMedia + { + SocialPostId = post != null ? post.Id : Guid.Empty, + Type = item.Type, + Urls = item.Urls, + PollQuestion = item.PollQuestion, + PollTotalVotes = item.PollTotalVotes, + PollEndsAt = item.PollEndsAt, + PollUserVoteId = item.PollUserVoteId + }, autoSave: true); + } + + foreach (var item in items.SocialPollOptions) + { + var post = await _socialPostRepository.FirstOrDefaultAsync(x => x.Content == item.PostContent); + if (post == null) + continue; + + var media = await _socialMediaRepository.FirstOrDefaultAsync(x => x.SocialPostId == post.Id && x.PollQuestion == item.PollQuestion); + if (media == null) + continue; + + var exists = await _socialPollOptionRepository.AnyAsync(x => x.SocialMediaId == media.Id && x.Text == item.Text); + if (exists) + continue; + + await _socialPollOptionRepository.InsertAsync(new SocialPollOption + { + SocialMediaId = media != null ? media.Id : Guid.Empty, + Text = item.Text, + Votes = item.Votes + }, autoSave: true); + } + + foreach (var item in items.SocialComments) + { + var post = await _socialPostRepository.FirstOrDefaultAsync(x => x.Content == item.PostContent); + + if (post == null) + continue; + + var exists = await _socialCommentRepository.AnyAsync(x => x.SocialPostId == post.Id && x.Content == item.Content); + if (exists) + continue; + + var user = await _repositoryUser.FindByNormalizedUserNameAsync(item.UserName); + await _socialCommentRepository.InsertAsync(new SocialComment + { + UserId = user != null ? user.Id : null, + SocialPostId = post != null ? post.Id : Guid.Empty, + Content = item.Content + }, autoSave: true); + } + + foreach (var item in items.SocialLikes) + { + var post = await _socialPostRepository.FirstOrDefaultAsync(x => x.Content == item.PostContent); + + if (post == null) + continue; + + var exists = await _socialLikeRepository.AnyAsync(x => x.SocialPostId == post.Id); + if (exists) + continue; + + var user = await _repositoryUser.FindByNormalizedUserNameAsync(item.UserName); + await _socialLikeRepository.InsertAsync(new SocialLike + { + SocialPostId = post != null ? post.Id : Guid.Empty, + UserId = user != null ? user.Id : null + }, autoSave: true); + } + //admin kullanının departmen ve pozisyonunu default olarak belirliyoruz var adminUser = await _repositoryUser.FindByNormalizedEmailAsync(PlatformConsts.AbpIdentity.User.AdminEmailDefaultValue); if (adminUser != null) diff --git a/ui/src/components/codeLayout/ComponentSelector.tsx b/ui/src/components/codeLayout/ComponentSelector.tsx index 1d4adc2..bb96056 100644 --- a/ui/src/components/codeLayout/ComponentSelector.tsx +++ b/ui/src/components/codeLayout/ComponentSelector.tsx @@ -23,7 +23,7 @@ const ComponentSelector: React.FC = ({ diff --git a/ui/src/views/admin/files/FileManager.tsx b/ui/src/views/admin/files/FileManager.tsx index f5d465b..3684fcb 100644 --- a/ui/src/views/admin/files/FileManager.tsx +++ b/ui/src/views/admin/files/FileManager.tsx @@ -746,7 +746,7 @@ const FileManager = () => { {isHostContext ? ( { /> diff --git a/ui/src/views/developerKit/SqlQueryManager.tsx b/ui/src/views/developerKit/SqlQueryManager.tsx index 07216b0..1ab0d3a 100644 --- a/ui/src/views/developerKit/SqlQueryManager.tsx +++ b/ui/src/views/developerKit/SqlQueryManager.tsx @@ -908,17 +908,16 @@ GO`, ))} - diff --git a/ui/src/views/intranet/Dashboard.tsx b/ui/src/views/intranet/Dashboard.tsx new file mode 100644 index 0000000..0e0075e --- /dev/null +++ b/ui/src/views/intranet/Dashboard.tsx @@ -0,0 +1,625 @@ +import React, { useState, useEffect } from 'react' +import { AnimatePresence } from 'framer-motion' +import dayjs from 'dayjs' +import relativeTime from 'dayjs/plugin/relativeTime' +import isBetween from 'dayjs/plugin/isBetween' +import localizedFormat from 'dayjs/plugin/localizedFormat' + +// Widgets +import TodayBirthdays from './widgets/TodayBirthdays' +import RecentDocuments from './widgets/RecentDocuments' +import Surveys from './widgets/Surveys' + +// Modals +import SurveyModal from './widgets/SurveyModal' +import AnnouncementModal from './widgets/AnnouncementModal' + +// Social Wall +import SocialWall from './SocialWall' +import { Container } from '@/components/shared' +import { usePermission } from '@/utils/hooks/usePermission' +import { + AnnouncementDto, + IntranetDashboardDto, + SurveyAnswerDto, + SurveyDto, +} from '@/proxy/intranet/models' +import { intranetService } from '@/services/intranet.service' +import Announcements from './widgets/Announcements' +import { useLocalization } from '@/utils/hooks/useLocalization' +import useLocale from '@/utils/hooks/useLocale' +import { currentLocalDate } from '@/utils/dateUtils' +import { useStoreState } from '@/store/store' + +dayjs.extend(relativeTime) +dayjs.extend(isBetween) +dayjs.extend(localizedFormat) + +const WIDGET_ORDER_KEY = 'dashboard-widget-order' + +const IntranetDashboard: React.FC = () => { + const { checkPermission } = usePermission() + const [selectedAnnouncement, setSelectedAnnouncement] = useState(null) + const [selectedSurvey, setSelectedSurvey] = useState(null) + const [showSurveyModal, setShowSurveyModal] = useState(false) + const [isDesignMode, setIsDesignMode] = useState(false) + const [widgetOrder, setWidgetOrder] = useState>({ + left: [], + center: [], + right: [], + }) + + const [intranetDashboard, setIntranetDashboard] = useState() + const { translate } = useLocalization() + const currentLocale = useLocale() + + const fetchIntranetDashboard = async () => { + const dashboard = await intranetService.getDashboard() + if (dashboard.data) { + setIntranetDashboard(dashboard.data) + } + } + + useEffect(() => { + fetchIntranetDashboard() + }, []) + + // Drag state'leri birleştirildi + const [dragState, setDragState] = useState<{ + draggedId: string | null + targetColumn: string | null + targetIndex: number | null + }>({ + draggedId: null, + targetColumn: null, + targetIndex: null, + }) + + const handleTakeSurvey = (survey: SurveyDto) => { + setSelectedSurvey(survey) + setShowSurveyModal(true) + } + + const handleSubmitSurvey = (answers: SurveyAnswerDto[]) => { + setShowSurveyModal(false) + setSelectedSurvey(null) + } + + // Widget metadata (component'lar yerine sadece meta bilgiler) + const widgetMetadata = [ + { id: 'today-birthdays', permission: 'AbpIdentity.Users.Widget', column: 'left' }, + { id: 'documents', permission: 'App.Files.Widget', column: 'left' }, + { id: 'active-surveys', permission: 'App.Intranet.Survey.Widget', column: 'left' }, + { id: 'social-wall', permission: 'App.Intranet.SocialPost.Widget', column: 'center' }, + { + id: 'announcements', + permission: 'App.Intranet.Announcement.Widget', + column: 'right', + }, + ] + + // If permissions arrive after mount, initialize default order when needed + const grantedPolicies = useStoreState((state) => state.abpConfig?.config?.auth.grantedPolicies) + + const initializeDefaultOrder = () => { + const defaultOrder = { + left: widgetMetadata + .filter((w) => w.column === 'left' && checkPermission(w.permission)) + .map((w) => w.id), + center: widgetMetadata + .filter((w) => w.column === 'center' && checkPermission(w.permission)) + .map((w) => w.id), + right: widgetMetadata + .filter((w) => w.column === 'right' && checkPermission(w.permission)) + .map((w) => w.id), + } + setWidgetOrder(defaultOrder) + } + + // Widget sıralamasını yükle — grantedPolicies gelince çalış ki checkPermission doğru çalışsın + useEffect(() => { + if (!grantedPolicies) return + + const savedOrder = localStorage.getItem(WIDGET_ORDER_KEY) + if (savedOrder) { + try { + const parsed = JSON.parse(savedOrder) as Record + const order: Record = { + left: [...new Set((parsed.left || []) as string[])], + center: [...new Set((parsed.center || []) as string[])], + right: [...new Set((parsed.right || []) as string[])], + } + + // Kaydedilmiş düzende olmayan ama izni olan widgetları varsayılan kolonuna ekle + const allAssigned = new Set([...order.left, ...order.center, ...order.right]) + widgetMetadata.forEach((w) => { + if (!allAssigned.has(w.id) && checkPermission(w.permission)) { + order[w.column as keyof typeof order].push(w.id) + } + }) + + setWidgetOrder(order) + } catch (error) { + console.error('Widget order parse error:', error) + initializeDefaultOrder() + } + } else { + initializeDefaultOrder() + } + }, [grantedPolicies]) + + // Widget sıralamasını kaydet + const saveWidgetOrder = (newOrder: Record) => { + setWidgetOrder(newOrder) + localStorage.setItem(WIDGET_ORDER_KEY, JSON.stringify(newOrder)) + } + + const handleDragStart = (e: React.DragEvent, widgetId: string, column: string) => { + setDragState({ draggedId: widgetId, targetColumn: null, targetIndex: null }) + e.dataTransfer.effectAllowed = 'move' + e.dataTransfer.setData('widgetId', widgetId) + e.dataTransfer.setData('sourceColumn', column) + } + + const handleDragEnterWidget = (e: React.DragEvent, column: string, index: number) => { + // Sadece widget'ın üst kısmına yakınsa indicator göster + const rect = (e.currentTarget as HTMLElement).getBoundingClientRect() + const mouseY = e.clientY + const widgetTop = rect.top + const widgetHeight = rect.height + const threshold = widgetHeight * 0.3 // Üst %30'luk alan + + if (mouseY - widgetTop < threshold) { + // Üst kısma yakın - indicator göster + setDragState((prev) => ({ ...prev, targetColumn: column, targetIndex: index })) + } else { + // Widget'ın ortasında veya altında - indicator gösterme + setDragState((prev) => ({ ...prev, targetColumn: column, targetIndex: null })) + } + } + + const handleDragEnterColumn = (column: string) => { + setDragState((prev) => ({ ...prev, targetColumn: column, targetIndex: null })) + } + + const handleDragLeaveColumn = () => { + setDragState((prev) => ({ ...prev, targetColumn: null, targetIndex: null })) + } + + const handleDrop = (e: React.DragEvent, targetColumn: string, targetIndex?: number) => { + e.preventDefault() + e.stopPropagation() + + const widgetId = e.dataTransfer.getData('widgetId') + const sourceColumn = e.dataTransfer.getData('sourceColumn') + + if (!widgetId || !sourceColumn) return + + const newOrder = { ...widgetOrder } + + // ÖNCE tüm kolonlardan bu widget'ı kaldır (duplicate önleme) + Object.keys(newOrder).forEach((col) => { + newOrder[col] = newOrder[col].filter((id) => id !== widgetId) + }) + + // SONRA hedef kolona ekle + if (targetIndex !== undefined) { + newOrder[targetColumn].splice(targetIndex, 0, widgetId) + } else { + newOrder[targetColumn].push(widgetId) + } + + // Duplicate'leri temizle + Object.keys(newOrder).forEach((col) => { + newOrder[col] = [...new Set(newOrder[col])] + }) + + saveWidgetOrder(newOrder) + setDragState({ draggedId: null, targetColumn: null, targetIndex: null }) + } + + const handleDragEnd = () => { + setDragState({ draggedId: null, targetColumn: null, targetIndex: null }) + } + + // Widget component'ını render et + const renderWidgetComponent = (widgetId: string) => { + switch (widgetId) { + case 'today-birthdays': + return + case 'documents': + return + case 'announcements': + return ( + + ) + case 'active-surveys': + return ( + + ) + case 'social-wall': + return + default: + return null + } + } + + // Widget'ları render et + const renderWidgets = (column: 'left' | 'center' | 'right') => { + const columnWidgets = widgetOrder[column] || [] + + // Duplicate'leri filtrele + const uniqueWidgets = [...new Set(columnWidgets)] + + return uniqueWidgets + .map((widgetId, index) => { + const metadata = widgetMetadata.find((w) => w.id === widgetId) + if (!metadata || !checkPermission(metadata.permission)) return null + + const isDragging = dragState.draggedId === widgetId + const isDropTarget = dragState.targetColumn === column && dragState.targetIndex === index + + return ( +
+ {/* Drop indicator - SADECE widget'ların arasına (üst %30'luk alana) gelince göster */} + {isDesignMode && isDropTarget && !isDragging && ( +
+ {/* Çizgi */} +
+ {/* Badge */} +
+ + + + Buraya Bırak +
+
+ )} + +
{ + if (isDesignMode) { + handleDragStart(e, widgetId, column) + // Drag ghost image'i gizle + const ghost = document.createElement('div') + ghost.style.opacity = '0' + e.dataTransfer.setDragImage(ghost, 0, 0) + } + }} + onDragOver={(e) => { + if (!isDesignMode) return + e.preventDefault() + e.stopPropagation() + // Throttle: Sadece düzenli aralıklarla güncelle + const now = Date.now() + if ( + !e.currentTarget.dataset.lastUpdate || + now - parseInt(e.currentTarget.dataset.lastUpdate) > 150 + ) { + e.currentTarget.dataset.lastUpdate = now.toString() + handleDragEnterWidget(e, column, index) + } + }} + onDragLeave={(e) => { + // Widget'tan çıkınca indicator'ı kaldır + if (isDesignMode) { + setDragState((prev) => ({ + ...prev, + targetColumn: prev.targetColumn, + targetIndex: null, + })) + } + }} + onDrop={(e) => { + if (!isDesignMode) return + e.stopPropagation() + + // Drop pozisyonunu hesapla + const rect = (e.currentTarget as HTMLElement).getBoundingClientRect() + const mouseY = e.clientY + const widgetTop = rect.top + const widgetHeight = rect.height + const threshold = widgetHeight * 0.3 + + if (mouseY - widgetTop < threshold) { + // Üst kısma bırak - mevcut index'e ekle + handleDrop(e, column, index) + } else { + // Alt kısma bırak - sonraki index'e ekle + handleDrop(e, column, index + 1) + } + }} + onDragEnd={handleDragEnd} + className={` + relative + ${ + isDesignMode + ? `border-2 border-dashed rounded-lg cursor-move + ${ + isDragging + ? 'border-blue-400 opacity-70 bg-blue-50/30 dark:bg-blue-900/10' + : 'border-gray-300 dark:border-gray-600 hover:border-blue-400 dark:hover:border-blue-500 hover:shadow-md' + } + transition-all duration-300 ease-out` + : 'border-0 transition-none' + } + `} + style={{ + touchAction: 'none', + transition: + 'border-color 0.3s ease-out, opacity 0.3s ease-out, box-shadow 0.3s ease-out', + willChange: isDragging ? 'opacity' : 'auto', + }} + > + {/* Dragging overlay - daha minimal */} + {isDesignMode && isDragging && ( +
+
+ + + + Taşınıyor +
+
+ )} +
+ {renderWidgetComponent(widgetId)} +
+
+
+ ) + }) + .filter(Boolean) + } + + return ( + +
+
+
+ {/* Design Mode Toggle */} +
+ + +
+ + {/* Reset Button - Sadece design mode aktifken görünsün */} + {isDesignMode && ( + + )} +
+ +
+

+ {translate('::AI.Welcome')},{' '} + {currentLocalDate(new Date(), currentLocale || 'tr')} +

+
+
+ +
+
{ + if (!isDesignMode) return + e.preventDefault() + // Throttle: Sadece her 150ms'de bir güncelle + const now = Date.now() + const target = e.currentTarget as HTMLElement + if ( + !target.dataset.lastColumnUpdate || + now - parseInt(target.dataset.lastColumnUpdate) > 150 + ) { + target.dataset.lastColumnUpdate = now.toString() + handleDragEnterColumn('left') + } + }} + onDragLeave={() => { + if (isDesignMode) handleDragLeaveColumn() + }} + onDrop={(e) => { + if (!isDesignMode) return + e.stopPropagation() + const columnWidgets = widgetOrder['left'] || [] + handleDrop(e, 'left', columnWidgets.length) + }} + > + {renderWidgets('left')} + {isDesignMode && + dragState.targetColumn === 'left' && + widgetOrder['left']?.length === 0 && ( +
+

+ + + + Widget'ı buraya bırakın +

+
+ )} +
+ +
{ + if (!isDesignMode) return + e.preventDefault() + const now = Date.now() + const target = e.currentTarget as HTMLElement + if ( + !target.dataset.lastColumnUpdate || + now - parseInt(target.dataset.lastColumnUpdate) > 150 + ) { + target.dataset.lastColumnUpdate = now.toString() + handleDragEnterColumn('center') + } + }} + onDragLeave={() => { + if (isDesignMode) handleDragLeaveColumn() + }} + onDrop={(e) => { + if (!isDesignMode) return + e.stopPropagation() + const columnWidgets = widgetOrder['center'] || [] + handleDrop(e, 'center', columnWidgets.length) + }} + > + {renderWidgets('center')} + {isDesignMode && + dragState.targetColumn === 'center' && + widgetOrder['center']?.length === 0 && ( +
+

+ Widget'ı buraya bırakın +

+
+ )} +
+ +
{ + if (!isDesignMode) return + e.preventDefault() + const now = Date.now() + const target = e.currentTarget as HTMLElement + if ( + !target.dataset.lastColumnUpdate || + now - parseInt(target.dataset.lastColumnUpdate) > 150 + ) { + target.dataset.lastColumnUpdate = now.toString() + handleDragEnterColumn('right') + } + }} + onDragLeave={() => { + if (isDesignMode) handleDragLeaveColumn() + }} + onDrop={(e) => { + if (!isDesignMode) return + e.stopPropagation() + const columnWidgets = widgetOrder['right'] || [] + handleDrop(e, 'right', columnWidgets.length) + }} + > + {renderWidgets('right')} + {isDesignMode && + dragState.targetColumn === 'right' && + widgetOrder['right']?.length === 0 && ( +
+

+ + + + Widget'ı buraya bırakın +

+
+ )} +
+
+
+ + + {showSurveyModal && selectedSurvey && ( + setShowSurveyModal(false)} + onSubmit={handleSubmitSurvey} + /> + )} + + + + {selectedAnnouncement && ( + setSelectedAnnouncement(null)} + /> + )} + +
+ ) +} + +export default IntranetDashboard diff --git a/ui/src/views/intranet/SocialWall/CreatePost.tsx b/ui/src/views/intranet/SocialWall/CreatePost.tsx new file mode 100644 index 0000000..20d0b87 --- /dev/null +++ b/ui/src/views/intranet/SocialWall/CreatePost.tsx @@ -0,0 +1,466 @@ +import React, { useState, useRef } from 'react' +import { motion, AnimatePresence } from 'framer-motion' +import classNames from 'classnames' +import EmojiPicker, { EmojiClickData } from 'emoji-picker-react' +import { + FaChartBar, + FaSmile, + FaTimes, + FaImages, + FaMapMarkerAlt +} from 'react-icons/fa' +import MediaManager from './MediaManager' +import LocationPicker from './LocationPicker' +import { SocialMediaDto } from '@/proxy/intranet/models' + +interface CreatePostProps { + onCreatePost: (post: { + content: string + location?: string + media?: { + type: 'mixed' | 'poll' + mediaItems?: SocialMediaDto[] + poll?: { + question: string + options: Array<{ text: string }> + } + } + }) => void +} + +import { useLocalization } from '@/utils/hooks/useLocalization' +import { useStoreState } from '@/store/store' +import { Avatar } from '@/components/ui' +import { AVATAR_URL } from '@/constants/app.constant' +const CreatePost: React.FC = ({ onCreatePost }) => { + const { translate } = useLocalization(); + const [content, setContent] = useState('') + const [mediaType, setMediaType] = useState<'media' | 'poll' | null>(null) + const [mediaItems, setMediaItems] = useState([]) + const [location, setLocation] = useState(null) + const [pollQuestion, setPollQuestion] = useState('') + const [pollOptions, setPollOptions] = useState(['', '']) + const [isExpanded, setIsExpanded] = useState(false) + const [showEmojiPicker, setShowEmojiPicker] = useState(false) + const [showMediaManager, setShowMediaManager] = useState(false) + const [showLocationPicker, setShowLocationPicker] = useState(false) + const textareaRef = useRef(null) + const emojiPickerRef = useRef(null) + const { user, tenant } = useStoreState((state) => state.auth) + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + + if (!content.trim() && mediaItems.length === 0 && !mediaType) return + + let media = undefined + + if (mediaType === 'media' && mediaItems.length > 0) { + media = { + type: 'mixed' as const, + mediaItems + } + } else if (mediaType === 'poll' && pollQuestion && pollOptions.filter(o => o.trim()).length >= 2) { + media = { + type: 'poll' as const, + poll: { + question: pollQuestion, + options: pollOptions.filter(o => o.trim()).map(text => ({ text })) + } + } + } + + onCreatePost({ + content, + media, + location: location || undefined + }) + + // Reset form + setContent('') + setMediaType(null) + setMediaItems([]) + setLocation(null) + setPollQuestion('') + setPollOptions(['', '']) + setIsExpanded(false) + setShowEmojiPicker(false) + } + + const handleEmojiClick = (emojiData: EmojiClickData) => { + const emoji = emojiData.emoji + const textarea = textareaRef.current + if (!textarea) return + + const start = textarea.selectionStart + const end = textarea.selectionEnd + const text = content + const before = text.substring(0, start) + const after = text.substring(end) + + setContent(before + emoji + after) + + // Set cursor position after emoji + setTimeout(() => { + textarea.selectionStart = textarea.selectionEnd = start + emoji.length + textarea.focus() + }, 0) + } + + const addPollOption = () => { + if (pollOptions.length < 6) { + setPollOptions([...pollOptions, '']) + } + } + + const removePollOption = (index: number) => { + if (pollOptions.length > 2) { + setPollOptions(pollOptions.filter((_, i) => i !== index)) + } + } + + const updatePollOption = (index: number, value: string) => { + const newOptions = [...pollOptions] + newOptions[index] = value + setPollOptions(newOptions) + } + + const clearMedia = () => { + setMediaType(null) + setMediaItems([]) + setPollQuestion('') + setPollOptions(['', '']) + } + + const removeMediaItem = (id: string | undefined) => { + if (!id) return + setMediaItems(mediaItems.filter((m) => m.id !== id)) + } + + // Close emoji picker when clicking outside + React.useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (emojiPickerRef.current && !emojiPickerRef.current.contains(event.target as Node)) { + setShowEmojiPicker(false) + } + } + + if (showEmojiPicker) { + document.addEventListener('mousedown', handleClickOutside) + } + + return () => { + document.removeEventListener('mousedown', handleClickOutside) + } + }, [showEmojiPicker]) + + return ( +
+
+ {/* Text Input */} +
+ +
+