Compare commits
19
Commits
c0bc89083d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a9316ed6f | ||
|
|
f3b1d901a8 | ||
|
|
df7e8827be | ||
|
|
2e477ca023 | ||
|
|
5292b99af6 | ||
|
|
3d83e95613 | ||
|
|
75b49be476 | ||
|
|
ba4976fce4 | ||
|
|
4eafa2fa8d | ||
|
|
70083f1230 | ||
|
|
9070bebb54 | ||
|
|
5d2e989ee9 | ||
|
|
ce2b3ba8c9 | ||
|
|
c9228950d5 | ||
|
|
2e7f9e7a27 | ||
|
|
d656229ab3 | ||
|
|
fa3b289a77 | ||
|
|
09ac6c6bb1 | ||
|
|
8228ff27b8 |
Vendored
+54
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "C#: FamilyTreeAPI",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "build",
|
||||||
|
"program": "${workspaceFolder}/FamilyTreeAPI/bin/Debug/net10.0/FamilyTreeAPI.dll",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"console": "internalConsole",
|
||||||
|
|
||||||
|
"env": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
|
"ASPNETCORE_URLS": "http://localhost:5019"
|
||||||
|
},
|
||||||
|
"serverReadyAction": {
|
||||||
|
"action": "openExternally",
|
||||||
|
"pattern": "\\bNow listening on:\\s+(https?://\\S+)",
|
||||||
|
"uriFormat": "%s/swagger/index.html"
|
||||||
|
},
|
||||||
|
|
||||||
|
"sourceFileMap": {
|
||||||
|
"/Views": "${workspaceFolder}/Views"
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": ".NET Core Launch (web) - Release",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "publish",
|
||||||
|
"program": "${workspaceFolder}/FamilyTreeAPI/bin/Release/net10.0/linux-x64/FamilyTreeAPI.dll",
|
||||||
|
"serverReadyAction": {
|
||||||
|
"action": "openExternally",
|
||||||
|
"pattern": "listening on:\\s+(https?://\\S+)",
|
||||||
|
"uriFormat": "%s/swagger/index.html"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Production",
|
||||||
|
"ASPNETCORE_URLS": "https://localhost:5019"
|
||||||
|
},
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+31
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "shell",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"${workspaceFolder}/FamilyTreeAPI/FamilyTreeAPI.csproj",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "publish",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"publish",
|
||||||
|
"${workspaceFolder}/FamilyTreeAPI/FamilyTreeAPI.csproj",
|
||||||
|
"-c",
|
||||||
|
"Release"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.7.34202.233
|
VisualStudioVersion = 17.7.34202.233
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using FamilyTreeAPI.Repository;
|
|||||||
|
|
||||||
namespace FamilyTreeAPI.Controllers;
|
namespace FamilyTreeAPI.Controllers;
|
||||||
|
|
||||||
|
using DocumentFormat.OpenXml.Drawing.Charts;
|
||||||
using FamilyTreeAPI.Interface;
|
using FamilyTreeAPI.Interface;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
@@ -110,14 +111,44 @@ public class FileUploadController : ControllerBase
|
|||||||
return Ok(ret);
|
return Ok(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("[action]")]
|
||||||
|
public async Task<IActionResult> DownloadPersonPhotoById(DeleteCriteria<int> criteria)
|
||||||
|
{
|
||||||
|
|
||||||
|
var result = await _personPhoto.DownloadPersonPhotoById(criteria.Id);
|
||||||
|
if (result.StatusCode > 0)
|
||||||
|
return File(result.Data.Content, result.Data.ContentType, result.Data.FileName);
|
||||||
|
else
|
||||||
|
return NotFound("not found image");
|
||||||
|
}
|
||||||
[HttpPost("[action]")]
|
[HttpPost("[action]")]
|
||||||
public async Task<IActionResult> DownloadPersonPhoto(DownloadFileCriteria criteria)
|
public async Task<IActionResult> DownloadPersonPhoto(DownloadFileCriteria criteria)
|
||||||
{
|
{
|
||||||
|
|
||||||
var result = await _personPhoto.DownloadPersonPhoto(criteria.Id, criteria.FileName);
|
var result = await _personPhoto.DownloadPersonPhotoPerson(criteria.Id,criteria.PhotoType ,criteria.FileName);
|
||||||
|
if (result.StatusCode > 0)
|
||||||
|
return File(result.Data.Content, result.Data.ContentType, result.Data.FileName);
|
||||||
|
else
|
||||||
|
return NotFound("not found image");
|
||||||
|
}
|
||||||
|
[HttpPost("[action]")]
|
||||||
|
public async Task<IActionResult> DownloadPersonPhoto64(DownloadFileCriteria criteria)
|
||||||
|
{
|
||||||
|
|
||||||
return File(result.Data.Content, result.Data.ContentType, result.Data.FileName);
|
var result = await _personPhoto.DownloadPersonPhotoPerson(criteria.Id,criteria.PhotoType ,criteria.FileName);
|
||||||
|
if (result.StatusCode > 0)
|
||||||
|
{
|
||||||
|
byte[] file64 = result.Data.Content;
|
||||||
|
string rval = Convert.ToBase64String(file64);
|
||||||
|
ResultModel<string> retval = new() {
|
||||||
|
Data = rval,
|
||||||
|
StatusCode = 1,
|
||||||
|
Message = ""
|
||||||
|
};
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound("not found image");
|
||||||
}
|
}
|
||||||
[HttpPost("[action]")]
|
[HttpPost("[action]")]
|
||||||
public async Task<ActionResult> DeletePersonPhoto(DeleteFileCriteria criteria)
|
public async Task<ActionResult> DeletePersonPhoto(DeleteFileCriteria criteria)
|
||||||
@@ -127,8 +158,18 @@ public class FileUploadController : ControllerBase
|
|||||||
if ( criteria.Id > 0)
|
if ( criteria.Id > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
ret = await _personPhoto.DeletePersonPhoto(criteria.Id);
|
ret = await _personPhoto.DeletePersonPhoto(criteria.Id, criteria.PhotoType);
|
||||||
}
|
}
|
||||||
return Ok(ret);
|
return Ok(ret);
|
||||||
}
|
}
|
||||||
|
[HttpPost("[action]")]
|
||||||
|
public async Task<ActionResult> DeletePersonPhotoById(DeleteCriteria<int> criteria)
|
||||||
|
{
|
||||||
|
|
||||||
|
ResultModel<int> ret = new();
|
||||||
|
|
||||||
|
ret = await _personPhoto.DeletePersonPhotoById(criteria.Id);
|
||||||
|
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace FamilyTreeAPI.Controllers
|
|||||||
{
|
{
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("[action]")]
|
[HttpPost("[action]")]
|
||||||
public async Task<IActionResult> UploadImage(IFormFile file)
|
public async Task<IActionResult> UploadImage(IFormFile file)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,8 +37,25 @@ public class UsersController : ControllerBase
|
|||||||
public async Task<IActionResult> LoginApiAD([FromBody] AuthenticateRequest model)
|
public async Task<IActionResult> LoginApiAD([FromBody] AuthenticateRequest model)
|
||||||
{
|
{
|
||||||
string remoteIpAddress = HttpContext.Connection.RemoteIpAddress?.ToString();
|
string remoteIpAddress = HttpContext.Connection.RemoteIpAddress?.ToString();
|
||||||
var response = await _userService.LoginApiAD(model, remoteIpAddress);
|
var rval = await _userService.LoginApiAD(model, remoteIpAddress);
|
||||||
return Ok(response);
|
if (rval.Data != null && rval.Data.Token != null)
|
||||||
|
{
|
||||||
|
// Configure cookie options
|
||||||
|
|
||||||
|
var cookieOptions = new CookieOptions
|
||||||
|
{
|
||||||
|
HttpOnly = true, // Blocks client-side JavaScript reading/theft
|
||||||
|
Secure = false, // Requires HTTPS connections
|
||||||
|
SameSite = SameSiteMode.Unspecified, // Prevents CSRF attacks
|
||||||
|
Expires = DateTimeOffset.UtcNow.AddDays(1), // Match your token lifespan
|
||||||
|
Path = "/" // Accessible across entire domain structure
|
||||||
|
};
|
||||||
|
|
||||||
|
// Write cookie into response headers
|
||||||
|
Response.Cookies.Append("token", rval.Data.Token, cookieOptions);
|
||||||
|
}
|
||||||
|
return Ok(rval);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("[action]")]
|
[HttpPost("[action]")]
|
||||||
@@ -51,6 +68,14 @@ public class UsersController : ControllerBase
|
|||||||
string token = Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
|
string token = Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
|
||||||
string remoteIpAddress = Request.HttpContext.Connection.RemoteIpAddress.ToString();
|
string remoteIpAddress = Request.HttpContext.Connection.RemoteIpAddress.ToString();
|
||||||
var response = await _userService.Logout(token, currentUser, remoteIpAddress);
|
var response = await _userService.Logout(token, currentUser, remoteIpAddress);
|
||||||
|
Response.Cookies.Delete("token", new CookieOptions
|
||||||
|
{
|
||||||
|
HttpOnly = true,
|
||||||
|
Secure = false,
|
||||||
|
SameSite = SameSiteMode.Unspecified,
|
||||||
|
Path = "/"
|
||||||
|
});
|
||||||
|
|
||||||
return Ok(response);
|
return Ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# This stage is used when running from VS in fast mode (Default for Debug configuration)
|
# This stage is used when running from VS in fast mode (Default for Debug configuration)
|
||||||
#FROM mcr.microsoft.com/dotnet/aspnet:9::.0 AS base
|
#FROM mcr.microsoft.com/dotnet/aspnet:9::.0 AS base
|
||||||
ARG BUILD_CONFIGURATION=Release
|
ARG BUILD_CONFIGURATION=Release
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
|
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY ["FamilyTreeAPI/FamilyTreeAPI.csproj", "FamilyTreeAPI/"]
|
COPY ["FamilyTreeAPI/FamilyTreeAPI.csproj", "FamilyTreeAPI/"]
|
||||||
RUN dotnet restore "./FamilyTreeAPI/FamilyTreeAPI.csproj"
|
RUN dotnet restore "./FamilyTreeAPI/FamilyTreeAPI.csproj"
|
||||||
@@ -31,7 +31,7 @@ FROM build AS publish
|
|||||||
RUN dotnet publish "./FamilyTreeAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false
|
RUN dotnet publish "./FamilyTreeAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false
|
||||||
|
|
||||||
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
|
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
|
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV ASPNETCORE_HTTP_PORTS=8080
|
ENV ASPNETCORE_HTTP_PORTS=8080
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|||||||
@@ -15,16 +15,19 @@ public class DownloadFileCriteria
|
|||||||
{
|
{
|
||||||
public string FileName { get; set; }
|
public string FileName { get; set; }
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public int PhotoType {get; set;}
|
||||||
}
|
}
|
||||||
public class UploadCriteria
|
public class UploadCriteria
|
||||||
{
|
{
|
||||||
public string FileName { get; set; }
|
public string FileName { get; set; }
|
||||||
public int PersonId { get; set; }
|
public int PersonId { get; set; }
|
||||||
|
public int PhotoType {get; set;}
|
||||||
public IFormFile File { get; set; }
|
public IFormFile File { get; set; }
|
||||||
}
|
}
|
||||||
public class DeleteFileCriteria
|
public class DeleteFileCriteria
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string Filename { get; set; }
|
public string Filename { get; set; }
|
||||||
|
public int PhotoType {get; set;}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,12 @@
|
|||||||
namespace FamilyTreeAPI.Entities;
|
namespace FamilyTreeAPI.Entities;
|
||||||
|
|
||||||
|
|
||||||
|
//photo Type string number
|
||||||
|
public enum enumPhotoType
|
||||||
|
{
|
||||||
|
Profile = 1,
|
||||||
|
Other = 2
|
||||||
|
}
|
||||||
public class PersonPhotoDto
|
public class PersonPhotoDto
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
@@ -7,28 +6,36 @@
|
|||||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
<PublishSingleFile>true</PublishSingleFile>
|
<PublishSingleFile>true</PublishSingleFile>
|
||||||
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
|
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||||
|
<AllowMissingPrunePackageData>true</AllowMissingPrunePackageData>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="HotChocolate.AspNetCore" Version="16.0.0" />
|
<PackageReference Include="HotChocolate.AspNetCore" Version="16.6.1" />
|
||||||
<PackageReference Include="HotChocolate.Data.EntityFramework" Version="16.0.0" />
|
<PackageReference Include="HotChocolate.Data.EntityFramework" Version="16.6.1" />
|
||||||
<PackageReference Include="HotChocolate.Pagination.EntityFramework" Version="14.3.1" />
|
<PackageReference Include="HotChocolate.Pagination.EntityFramework" Version="14.3.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.7" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.11" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.7" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.11" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.11">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.7">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.11">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.3" />
|
||||||
<PackageReference Include="SpreadsheetLight" Version="3.5.0" />
|
<PackageReference Include="SpreadsheetLight" Version="3.5.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.7" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.3" />
|
||||||
|
<PackageReference Include="System.Drawing.Common" Version="10.0.11" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Update="appsettings.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="appsettings.Development.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
{
|
{
|
||||||
public class Helpers
|
public class Helpers
|
||||||
{
|
{
|
||||||
|
public static string GetFileExtension(string fileName)
|
||||||
|
{
|
||||||
|
string result = System.IO.Path.GetExtension(fileName);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
public static string GetFileContent(string extension)
|
public static string GetFileContent(string extension)
|
||||||
{
|
{
|
||||||
string contentType = "";
|
string contentType = "";
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ namespace FamilyTreeAPI.Interface;
|
|||||||
public interface IPersonPhoto
|
public interface IPersonPhoto
|
||||||
{
|
{
|
||||||
Task<ResultModel<int>> SaveAsync(UploadCriteria criteria);
|
Task<ResultModel<int>> SaveAsync(UploadCriteria criteria);
|
||||||
Task<ResultModel<FileContent>> DownloadPersonPhoto(int id, string? filename);
|
Task<ResultModel<FileContent>> DownloadPersonPhotoPerson(int personId, int photoType, string filename);
|
||||||
|
Task<ResultModel<FileContent>> DownloadPersonPhotoById(int id);
|
||||||
Task<ResultModel<int>> DeletePersonPhoto(int id);
|
Task<ResultModel<int>> DeletePersonPhoto(int id, int photoType);
|
||||||
|
Task<ResultModel<int>> DeletePersonPhotoById(int id);
|
||||||
Task<ResultModel<List<PersonPhotoDto>>> LoadPersonPhoto(int personId);
|
Task<ResultModel<List<PersonPhotoDto>>> LoadPersonPhoto(int personId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
|
|||||||
using Microsoft.EntityFrameworkCore.Storage;
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DocumentFormat.OpenXml.Office2010.Drawing.Charts;
|
|
||||||
using FamilyTreeAPI.Authorization;
|
using FamilyTreeAPI.Authorization;
|
||||||
using FamilyTreeAPI.Entities;
|
using FamilyTreeAPI.Entities;
|
||||||
using FamilyTreeAPI.GraphQL.Query;
|
using FamilyTreeAPI.GraphQL.Query;
|
||||||
@@ -14,6 +13,15 @@ using FamilyTreeAPI.Repository;
|
|||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
builder.Logging.ClearProviders();
|
||||||
|
builder.Logging.AddConsole();
|
||||||
|
builder.Logging.AddDebug();
|
||||||
|
// Explicitly register the base paths for Linux container execution
|
||||||
|
builder.Configuration
|
||||||
|
.SetBasePath(AppContext.BaseDirectory) // <-- Pulls from wherever the binary sits
|
||||||
|
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
|
||||||
|
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true)
|
||||||
|
.AddEnvironmentVariables();
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
#region Services
|
#region Services
|
||||||
var services = builder.Services;
|
var services = builder.Services;
|
||||||
@@ -22,19 +30,25 @@ services.AddControllers();
|
|||||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||||
services.AddEndpointsApiExplorer();
|
services.AddEndpointsApiExplorer();
|
||||||
services.AddSwaggerGen();
|
services.AddSwaggerGen();
|
||||||
|
string skey = "Super Secret SIGN AND VERIFY JWT TOKENS";
|
||||||
|
|
||||||
|
|
||||||
var appSettingsSection = builder.Configuration.GetSection("AppSettings");
|
var appSettingsSection = builder.Configuration.GetSection("AppSettings");
|
||||||
string skey = "";
|
if (appSettingsSection.Exists())
|
||||||
if (appSettingsSection == null)
|
|
||||||
{
|
|
||||||
skey = builder.Configuration.GetValue<string>("AppSettings:SecretKey");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
services.Configure<AppSettings>(appSettingsSection);
|
services.Configure<AppSettings>(appSettingsSection);
|
||||||
var appSettings = appSettingsSection.Get<AppSettings>();
|
var appSettings = appSettingsSection.Get<AppSettings>();
|
||||||
skey = appSettings.Secret;
|
if ( appSettings != null)
|
||||||
|
skey = appSettings.Secret;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string tkey = builder.Configuration.GetValue<string>("AppSettings:Secret") ?? string.Empty;
|
||||||
|
if (!string.IsNullOrEmpty(tkey))
|
||||||
|
skey = tkey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var key = Encoding.ASCII.GetBytes(skey);
|
var key = Encoding.ASCII.GetBytes(skey);
|
||||||
|
|
||||||
services.AddAuthentication(x =>
|
services.AddAuthentication(x =>
|
||||||
@@ -122,7 +136,16 @@ using (var scope = app.Services.CreateScope())
|
|||||||
//if (!databaseCreator.Exists())
|
//if (!databaseCreator.Exists())
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
databaseCreator.CreateTables();
|
// Check if database exists
|
||||||
|
if (!databaseCreator.Exists())
|
||||||
|
{
|
||||||
|
databaseCreator.Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!databaseCreator.HasTables())
|
||||||
|
{
|
||||||
|
databaseCreator.CreateTables();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -164,6 +187,17 @@ app.Run();
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Update="appsettings.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="appsettings.Development.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
|
|
||||||
https://www.youtube.com/watch?v=WQFx2m5Ub9M
|
https://www.youtube.com/watch?v=WQFx2m5Ub9M
|
||||||
|
|
||||||
|
|
||||||
@@ -179,14 +213,43 @@ PM> Scaffold-DbContext "Host=postgresdb;Port=5432;database=FamilyTreeDB;user id=
|
|||||||
https://www.youtube.com/watch?v=HnXA8RI7Tvc
|
https://www.youtube.com/watch?v=HnXA8RI7Tvc
|
||||||
|
|
||||||
query {
|
query {
|
||||||
family {
|
persons {
|
||||||
nodes{
|
nodes{
|
||||||
id
|
id
|
||||||
firstname
|
firstName
|
||||||
lastname
|
sex
|
||||||
email
|
email
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dotnet --list-sdks
|
||||||
|
|
||||||
|
In the VS Code Explorer, click and open your <ProjectName>.csproj file.
|
||||||
|
Locate the <TargetFramework> tag inside the <PropertyGroup> block.
|
||||||
|
Change the value to your desired version (e.g., change net11.0 or net9.0 to net10.0
|
||||||
|
|
||||||
|
now run to see out of date
|
||||||
|
|
||||||
|
dotnet list package --outdated
|
||||||
|
|
||||||
|
dotnet tool uninstall --global dotnet-outdated
|
||||||
|
dotnet tool install --global dotnet-outdated-tool
|
||||||
|
|
||||||
|
//update the outdate
|
||||||
|
dotnet outdated -u
|
||||||
|
|
||||||
|
update the package
|
||||||
|
dotnet add package <Package_Name>
|
||||||
|
|
||||||
|
Open the .vscode folder in your workspace and select launch.json.
|
||||||
|
Look for lines containing your old framework directory string (e.g., /bin/Debug/net8.0/).
|
||||||
|
Update those paths to reflect your new version (e.g., /bin/Debug/net9.0/).
|
||||||
|
|
||||||
|
clear and rebuild
|
||||||
|
|
||||||
|
dotnet clean
|
||||||
|
dotnet restore
|
||||||
|
dotnet build
|
||||||
*/
|
*/
|
||||||
@@ -8,35 +8,17 @@
|
|||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
},
|
},
|
||||||
"dotnetRunMessages": true,
|
"dotnetRunMessages": true,
|
||||||
"applicationUrl": "http://localhost:5016",
|
"applicationUrl": "http://localhost:5016"
|
||||||
"applicationUrl1": "http://192.168.8.188:5015"
|
|
||||||
},
|
},
|
||||||
"IIS Express": {
|
"http": {
|
||||||
"commandName": "IISExpress",
|
"commandName": "Project",
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"launchUrl": "swagger",
|
"launchUrl": "swagger",
|
||||||
"environmentVariables": {
|
"applicationUrl": "http://localhost:5000"
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"Container (Dockerfile)": {
|
|
||||||
"commandName": "Docker",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_HTTP_PORTS": "8080"
|
|
||||||
},
|
|
||||||
"publishAllPorts": true,
|
|
||||||
"useSSL": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:4559",
|
|
||||||
"sslPort": 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ using FamilyTreeAPI.Entities;
|
|||||||
using FamilyTreeAPI.Helper;
|
using FamilyTreeAPI.Helper;
|
||||||
using FamilyTreeAPI.Interface;
|
using FamilyTreeAPI.Interface;
|
||||||
using FamilyTreeAPI.Models;
|
using FamilyTreeAPI.Models;
|
||||||
|
using HotChocolate.CostAnalysis.Types;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace FamilyTreeAPI.Repository
|
namespace FamilyTreeAPI.Repository
|
||||||
@@ -31,12 +32,12 @@ namespace FamilyTreeAPI.Repository
|
|||||||
dto.PhotoType = model.PhotoType;
|
dto.PhotoType = model.PhotoType;
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
private PersonPhoto FillModel(PersonPhoto model, int personId, string filename)
|
private PersonPhoto FillModel(PersonPhoto model, int personId, int photoType, string filename)
|
||||||
{
|
{
|
||||||
|
|
||||||
model.PersonId = personId;
|
model.PersonId = personId;
|
||||||
model.Photo = filename;
|
model.Photo = filename;
|
||||||
model.PhotoType = System.IO.Path.GetExtension(filename);
|
model.PhotoType = photoType.ToString(); //System.IO.Path.GetExtension(filename);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
@@ -44,8 +45,10 @@ namespace FamilyTreeAPI.Repository
|
|||||||
{
|
{
|
||||||
int result = default(int);
|
int result = default(int);
|
||||||
int statuscode = 0;
|
int statuscode = 0;
|
||||||
string error = "";
|
string error = "";//Other
|
||||||
|
string photoType = "2"; //
|
||||||
|
if (criteria.PhotoType > 0)
|
||||||
|
photoType = criteria.PhotoType.ToString();
|
||||||
HttpContext? httpContext = _httpContext.HttpContext;
|
HttpContext? httpContext = _httpContext.HttpContext;
|
||||||
string loginName = "";
|
string loginName = "";
|
||||||
if (httpContext != null)
|
if (httpContext != null)
|
||||||
@@ -63,7 +66,7 @@ namespace FamilyTreeAPI.Repository
|
|||||||
|
|
||||||
model = new();
|
model = new();
|
||||||
|
|
||||||
model = FillModel(model,criteria.PersonId, formfile.FileName);
|
model = FillModel(model,criteria.PersonId, criteria.PhotoType,formfile.FileName);
|
||||||
|
|
||||||
using (var stream = new MemoryStream())
|
using (var stream = new MemoryStream())
|
||||||
{
|
{
|
||||||
@@ -90,15 +93,50 @@ namespace FamilyTreeAPI.Repository
|
|||||||
Message = error
|
Message = error
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
public async Task<ResultModel<FileContent>> DownloadPersonPhotoById(int Id)
|
||||||
public async Task<ResultModel<FileContent>> DownloadPersonPhoto(int id, string? filename)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
int statusCode = -1;
|
int statusCode = -1;
|
||||||
string error = "";
|
string error = "";
|
||||||
|
string extension = "";
|
||||||
PersonPhoto? model = null;
|
PersonPhoto? model = null;
|
||||||
FileContent fileContent = new();
|
FileContent fileContent = new();
|
||||||
if (id < 1)
|
try {
|
||||||
|
|
||||||
|
model = await _context.PersonPhotos.FindAsync(Id);
|
||||||
|
|
||||||
|
|
||||||
|
if (model != null)
|
||||||
|
{
|
||||||
|
extension = Helpers.GetFileExtension(model.Photo);
|
||||||
|
fileContent.ContentType = Helpers.GetFileContent(extension);
|
||||||
|
fileContent.Content = (byte[])model.ImagePhoto;
|
||||||
|
fileContent.FileName = model.Photo;
|
||||||
|
statusCode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
error = e.ToString();
|
||||||
|
statusCode = -1;
|
||||||
|
}
|
||||||
|
return new ResultModel<FileContent>()
|
||||||
|
{
|
||||||
|
Data = fileContent,
|
||||||
|
StatusCode = statusCode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<FileContent>> DownloadPersonPhotoPerson(int personId, int photoType, string filename)
|
||||||
|
{
|
||||||
|
|
||||||
|
int statusCode = -1;
|
||||||
|
string error = "";
|
||||||
|
string extension = "";
|
||||||
|
PersonPhoto? model = null;
|
||||||
|
FileContent fileContent = new();
|
||||||
|
if (personId < 1)
|
||||||
{
|
{
|
||||||
var rlist = await _context.PersonPhotos.Where(x => x.Photo == filename).ToListAsync();
|
var rlist = await _context.PersonPhotos.Where(x => x.Photo == filename).ToListAsync();
|
||||||
if (rlist != null)
|
if (rlist != null)
|
||||||
@@ -109,19 +147,26 @@ namespace FamilyTreeAPI.Repository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
model = await _context.PersonPhotos.FindAsync(id);
|
var rlist = await _context.PersonPhotos.Where (x => x.PersonId == personId && photoType.ToString() == x.PhotoType).ToListAsync();
|
||||||
|
for ( int i = 0; i < rlist.Count; i++)
|
||||||
|
{
|
||||||
|
model = rlist[i];
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model != null)
|
if (model != null)
|
||||||
{
|
{
|
||||||
fileContent.ContentType = Helpers.GetFileContent(model.PhotoType);
|
extension = Helpers.GetFileExtension(model.Photo);
|
||||||
|
fileContent.ContentType = Helpers.GetFileContent(extension);
|
||||||
fileContent.Content = (byte[])model.ImagePhoto;
|
fileContent.Content = (byte[])model.ImagePhoto;
|
||||||
fileContent.FileName = model.Photo;
|
fileContent.FileName = model.Photo;
|
||||||
statusCode = 1;
|
statusCode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ResultModel<FileContent>()
|
return new ResultModel<FileContent>()
|
||||||
{
|
{
|
||||||
Data = fileContent,
|
Data = fileContent,
|
||||||
@@ -130,20 +175,69 @@ namespace FamilyTreeAPI.Repository
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ResultModel<int>> DeletePersonPhoto(int id)
|
public async Task<ResultModel<int>> DeletePersonPhoto(int personId, int photoType)
|
||||||
{
|
{
|
||||||
int result = default(int);
|
int result = default(int);
|
||||||
int statuscode = 0;
|
int statuscode = 0;
|
||||||
string error = "";
|
string error = "";
|
||||||
|
PersonPhoto? model;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PersonPhoto? model = await _context.PersonPhotos.FindAsync(id);
|
if (photoType < 1)
|
||||||
if (model != null)
|
|
||||||
{
|
{
|
||||||
_context.PersonPhotos.Remove(model);
|
List<PersonPhoto> list = await _context.PersonPhotos.Where ( x => x.PersonId == personId).ToListAsync();
|
||||||
await _context.SaveChangesAsync();
|
for (int i = 0; i< list.Count; i++)
|
||||||
statuscode = 1;
|
{
|
||||||
|
model = list[i];
|
||||||
|
_context.PersonPhotos.Remove(model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<PersonPhoto> list = await _context.PersonPhotos.Where ( x => x.PersonId == personId && x.PhotoType == photoType.ToString()).ToListAsync();
|
||||||
|
for (int i = 0; i< list.Count; i++)
|
||||||
|
{
|
||||||
|
model = list[i];
|
||||||
|
_context.PersonPhotos.Remove(model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = -1;
|
||||||
|
}
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
return new ResultModel<int>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<int>> DeletePersonPhotoById(int id)
|
||||||
|
{
|
||||||
|
int result = default(int);
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
PersonPhoto? model = await _context.PersonPhotos.FindAsync(id);
|
||||||
|
if (model != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
_context.PersonPhotos.Remove(model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ public partial class PersonRepository : IPerson
|
|||||||
node.Key = item.Id.ToString();
|
node.Key = item.Id.ToString();
|
||||||
node.Type = type;
|
node.Type = type;
|
||||||
if (item.Image != null)
|
if (item.Image != null)
|
||||||
node.Data.Image = await LoadPersonImage(item.Image);
|
node.Data.Image = await LoadPersonImage(item.Id, (int) enumPhotoType.Profile, item.Image);
|
||||||
|
|
||||||
node.Icon = "T";
|
node.Icon = "T";
|
||||||
node.StyleClass = getStyleClass(node.Icon);
|
node.StyleClass = getStyleClass(node.Icon);
|
||||||
@@ -319,8 +319,8 @@ public partial class PersonRepository : IPerson
|
|||||||
TreeNode<TreeData> child;
|
TreeNode<TreeData> child;
|
||||||
PersonDto dto;
|
PersonDto dto;
|
||||||
Person pe;
|
Person pe;
|
||||||
int fatherId, motherId;
|
int fatherId, motherId, personId;
|
||||||
fatherId = motherId = 0;
|
personId = fatherId = motherId = 0;
|
||||||
string data = person.Sex;
|
string data = person.Sex;
|
||||||
TreeNode<TreeData> citem;
|
TreeNode<TreeData> citem;
|
||||||
string pName = "";
|
string pName = "";
|
||||||
@@ -371,6 +371,7 @@ public partial class PersonRepository : IPerson
|
|||||||
pName = pe.FirstName;
|
pName = pe.FirstName;
|
||||||
image = pe.Image;
|
image = pe.Image;
|
||||||
key = motherId.ToString();
|
key = motherId.ToString();
|
||||||
|
personId = motherId;
|
||||||
data = pe.Sex;
|
data = pe.Sex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,6 +383,7 @@ public partial class PersonRepository : IPerson
|
|||||||
pName = pe.FirstName;
|
pName = pe.FirstName;
|
||||||
image = pe.Image;
|
image = pe.Image;
|
||||||
key = fatherId.ToString();
|
key = fatherId.ToString();
|
||||||
|
personId = fatherId;
|
||||||
data = pe.Sex;
|
data = pe.Sex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -390,7 +392,7 @@ public partial class PersonRepository : IPerson
|
|||||||
citem.Data = new();
|
citem.Data = new();
|
||||||
citem.Label = pName;
|
citem.Label = pName;
|
||||||
if (image != null)
|
if (image != null)
|
||||||
citem.Data.Image = await LoadPersonImage(image);
|
citem.Data.Image = await LoadPersonImage(personId, (int) enumPhotoType.Profile, image);
|
||||||
|
|
||||||
citem.Icon = "P";
|
citem.Icon = "P";
|
||||||
|
|
||||||
@@ -411,7 +413,7 @@ public partial class PersonRepository : IPerson
|
|||||||
child.Type = type;
|
child.Type = type;
|
||||||
image = dto.Image;
|
image = dto.Image;
|
||||||
if (image != null)
|
if (image != null)
|
||||||
child.Data.Image = await LoadPersonImage(image);
|
child.Data.Image = await LoadPersonImage(dto.Id,(int) enumPhotoType.Profile, image);
|
||||||
child.Icon = "C";
|
child.Icon = "C";
|
||||||
child.StyleClass = getStyleClass(child.Icon);
|
child.StyleClass = getStyleClass(child.Icon);
|
||||||
child.Label = dto.FirstName;
|
child.Label = dto.FirstName;
|
||||||
@@ -480,12 +482,12 @@ public partial class PersonRepository : IPerson
|
|||||||
/// <param name="fileName"></param>
|
/// <param name="fileName"></param>
|
||||||
/// <param name="familyId"></param>
|
/// <param name="familyId"></param>
|
||||||
/// <param name="base64"></param>
|
/// <param name="base64"></param>
|
||||||
private string SaveFile(string fileName, int familyId, string base64)
|
private async Task<string> SaveFile(string fileName, int personId, string base64)
|
||||||
{
|
{
|
||||||
string path = "";
|
string path = "";
|
||||||
|
|
||||||
int statusCode = 0;
|
int statusCode = 0;
|
||||||
string error = "";
|
// string error = "";
|
||||||
string sdate = GetCurrentDateTime();
|
string sdate = GetCurrentDateTime();
|
||||||
string filename, extention;
|
string filename, extention;
|
||||||
filename = extention = "";
|
filename = extention = "";
|
||||||
@@ -494,14 +496,33 @@ public partial class PersonRepository : IPerson
|
|||||||
string rbase = base64.Substring(first, last - first);
|
string rbase = base64.Substring(first, last - first);
|
||||||
|
|
||||||
byte[] newBytes = Convert.FromBase64String(rbase);
|
byte[] newBytes = Convert.FromBase64String(rbase);
|
||||||
|
extention = System.IO.Path.GetExtension(fileName);
|
||||||
|
filename = personId + "_" + sdate + extention;
|
||||||
|
|
||||||
|
// Wrap the byte array in a MemoryStream
|
||||||
|
var stream = new MemoryStream(newBytes);
|
||||||
|
|
||||||
|
// Create the IFormFile instance
|
||||||
|
IFormFile file = new FormFile(stream, 0, newBytes.Length, "Profile", filename)
|
||||||
|
{
|
||||||
|
Headers = new HeaderDictionary(),
|
||||||
|
ContentType = "application/octet-stream" // Change to your specific MIME type if known (e.g., "image/jpeg", "application/pdf")
|
||||||
|
};
|
||||||
|
//save to database.
|
||||||
|
UploadCriteria criteria = new();
|
||||||
|
criteria.FileName = filename;
|
||||||
|
criteria.PersonId = personId;
|
||||||
|
criteria.PhotoType = (int) enumPhotoType.Profile;
|
||||||
|
criteria.File = file;
|
||||||
|
var rval = await _personPhoto.SaveAsync(criteria);
|
||||||
|
|
||||||
|
/*
|
||||||
path = _config["AppSettings:ImageFolder"];
|
path = _config["AppSettings:ImageFolder"];
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
extention = System.IO.Path.GetExtension(fileName);
|
|
||||||
filename = familyId + "_" + sdate + extention;
|
|
||||||
string fullpath = System.IO.Path.Combine(path, filename);
|
string fullpath = System.IO.Path.Combine(path, filename);
|
||||||
/*
|
/*
|
||||||
using (var fileStream = new FileStream(fullpath, FileMode.Create))
|
using (var fileStream = new FileStream(fullpath, FileMode.Create))
|
||||||
@@ -520,10 +541,12 @@ public partial class PersonRepository : IPerson
|
|||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
using (FileStream fileStream = new FileStream(fullpath, FileMode.Create, FileAccess.Write, FileShare.None))
|
using (FileStream fileStream = new FileStream(fullpath, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||||
{
|
{
|
||||||
fileStream.Write(newBytes, 0, newBytes.Length);
|
fileStream.Write(newBytes, 0, newBytes.Length);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
@@ -538,7 +561,7 @@ public partial class PersonRepository : IPerson
|
|||||||
string loginName = "";
|
string loginName = "";
|
||||||
if (httpContext != null)
|
if (httpContext != null)
|
||||||
{
|
{
|
||||||
UserDto? user = (UserDto?)httpContext.Items["User"];
|
UserDto? user = (UserDto?)httpContext.Items["User"];
|
||||||
if (user != null)
|
if (user != null)
|
||||||
loginName = user.FirstName + " " + user.LastName;
|
loginName = user.FirstName + " " + user.LastName;
|
||||||
}
|
}
|
||||||
@@ -571,7 +594,7 @@ public partial class PersonRepository : IPerson
|
|||||||
if (!string.IsNullOrEmpty(container.FileName))
|
if (!string.IsNullOrEmpty(container.FileName))
|
||||||
{
|
{
|
||||||
|
|
||||||
string image = SaveFile(container.FileName, result, container.FormData);
|
string image = await SaveFile(container.FileName, result, container.FormData);
|
||||||
// update the image in table to new
|
// update the image in table to new
|
||||||
model.Image = image;
|
model.Image = image;
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
@@ -587,7 +610,7 @@ public partial class PersonRepository : IPerson
|
|||||||
result = item.Id;
|
result = item.Id;
|
||||||
if (!string.IsNullOrEmpty(container.FileName))
|
if (!string.IsNullOrEmpty(container.FileName))
|
||||||
{
|
{
|
||||||
string image = SaveFile(container.FileName, result, container.FormData);
|
string image = await SaveFile(container.FileName, result, container.FormData);
|
||||||
// update the image in table to new
|
// update the image in table to new
|
||||||
model1.Image = image;
|
model1.Image = image;
|
||||||
}
|
}
|
||||||
@@ -714,17 +737,37 @@ public partial class PersonRepository : IPerson
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> LoadPersonImage(string filename)
|
private async Task<string> LoadPersonImage_old(string filename)
|
||||||
{
|
{
|
||||||
string result = "";
|
string result = "";
|
||||||
|
|
||||||
DownloadFileCriteria criteria = new() { FileName = filename };
|
DownloadFileCriteria criteria = new() { FileName = filename };
|
||||||
var resultModel = await _importPersonRepository.DownloadFile(criteria);
|
var resultModel = await _importPersonRepository.DownloadFile(criteria);
|
||||||
if (!string.IsNullOrEmpty((resultModel.Data)))
|
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(resultModel.Data))
|
||||||
result = "data:image/png;base64," + resultModel.Data;
|
result = "data:image/png;base64," + resultModel.Data;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<string> LoadPersonImage(int personId, int photoType, string filename)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
|
||||||
|
// DownloadFileCriteria criteria = new() { FileName = filename };
|
||||||
|
|
||||||
|
var resultModel = await _personPhoto.DownloadPersonPhotoPerson(personId, photoType , filename);
|
||||||
|
if (resultModel.StatusCode > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
string base64String = Convert.ToBase64String(resultModel.Data.Content);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(base64String))
|
||||||
|
result = "data:image/png;base64," + base64String;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public ResultModel<int> DeleteUploadFile(DeleteFileCriteria criteria)
|
public ResultModel<int> DeleteUploadFile(DeleteFileCriteria criteria)
|
||||||
{
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ public class Seed
|
|||||||
var conn = _context.Database.GetDbConnection();
|
var conn = _context.Database.GetDbConnection();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
conn.Open();
|
conn.Open();
|
||||||
var command = conn.CreateCommand();
|
var command = conn.CreateCommand();
|
||||||
command.CommandText = sptext;
|
command.CommandText = sptext;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
|
|
||||||
"AppSettings": {
|
"AppSettings": {
|
||||||
"Secret": "Nepean Blue Mountain Super Secret SIGN AND VERIFY JWT TOKENS, BEARER TOKEN USE WHEN CALLING THIS API.",
|
"Secret": "Super Secret SIGN AND VERIFY JWT TOKENS, BEARER TOKEN USE WHEN CALLING THIS API.",
|
||||||
"SQLConnectionString": "host=localhost;port=5432;database=FamilyTreeDB;username=postgres;password=Positive~1;",
|
"iSQLConnectionString_i": "host=localhost;port=5432;database=familytreedb;username=postgres;password=Positive~1;",
|
||||||
"SQLConnectionString_vm": "host=192.168.1.240;port=5432;database=FamilyTreeDB;username=postgres;password=Positive~1;",
|
"SQLConnectionString": "host=127.0.0.1;port=5432;database=familytreedb;username=postgres;password=Positive~1;",
|
||||||
|
|
||||||
"ImageFolder": "c:\\temp\\Family",
|
"ImageFolder": "/temp/Family",
|
||||||
"ImportFolder": "c:\\temp"
|
"ImportFolder": "/temp"
|
||||||
|
|
||||||
},
|
},
|
||||||
"Logging": {
|
"Logging": {
|
||||||
@@ -17,11 +17,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"Kestrel_not_use": {
|
|
||||||
|
"Kestrel": {
|
||||||
"Endpoints": {
|
"Endpoints": {
|
||||||
"Http": {
|
"Http": {
|
||||||
"Url": "http://*:5015"
|
"Url": "http://localhost:5016"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=ASP.NET Core Web App running on Ubuntu
|
Description=ASP.NET Core Web App running on arch linux
|
||||||
[Service]
|
[Service]
|
||||||
WorkingDirectory=/var/www/familytree/api
|
WorkingDirectory=/var/www/familytree/api
|
||||||
ExecStart=/usr/bin/dotnet /var/www/familytree/api/FamilyTreeAPI.dll
|
ExecStart=/usr/bin/dotnet /var/www/familytree/api/FamilyTreeAPI.dll
|
||||||
Restart=always
|
Restart=always
|
||||||
# Restart service after 10 seconds if the dotnet service crashes:
|
# Restart service after 20 seconds if the dotnet service crashes:
|
||||||
RestartSec=10
|
RestartSec=20
|
||||||
KillSignal=SIGINT
|
KillSignal=SIGINT
|
||||||
SyslogIdentifier=dotnet-web-familytree-api
|
SyslogIdentifier=dotnet-web-familytree-api
|
||||||
# This user should exist on the server and have ownership of the deployment directory
|
# This user should exist on the server and have ownership of the deployment directory
|
||||||
User=www-data
|
#User=www-data this is other ubuntu
|
||||||
|
#arch linux has user http
|
||||||
|
User=http
|
||||||
Environment=ASPNETCORE_ENVIRONMENT=Production
|
Environment=ASPNETCORE_ENVIRONMENT=Production
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
#make sure in nginx.conf has include module.d/*.conf inside http block one.
|
#make sure in nginx.conf has include module.d/*.conf inside http block one.
|
||||||
server {
|
server {
|
||||||
listen 80; #make nginx out side listen 82;
|
listen 80; #make nginx out side listen 82;
|
||||||
location / {
|
location /familytreeapi/ {
|
||||||
proxy_pass http://127.0.0.1:5000;
|
#proxy_pass http://127.0.0.1:5015;
|
||||||
|
proxy_pass http://192.168.1.219:5015/;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection keep-alive;
|
proxy_set_header Connection keep-alive;
|
||||||
@@ -13,20 +14,29 @@
|
|||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 301 /familytreeui/; #if same one redirect to /familytreeui/
|
||||||
|
}
|
||||||
|
|
||||||
|
location /familytreeui {
|
||||||
|
return 301 /familytreeui/; #if same one redirect to /familytreeui/
|
||||||
|
}
|
||||||
|
|
||||||
location /familytreeui/ {
|
location /familytreeui/ {
|
||||||
root /var/www/familytree; #path must exist like /var/www/familytree/familytreeui and /var/www/familytree/api folder.
|
#root /var/www/familytree/; #path is real must exist like /var/www/familytree/familytreeui and /var/www/familytree/api folder.
|
||||||
index index.html
|
alias /var/www/familytree/ui/; #location does not to match. but angular index baseurl must same as location.
|
||||||
try_files $uri $uri/ /index.html;
|
#index index.html;
|
||||||
|
try_files $uri $uri/ /familytreeui/index.html /index.html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Optional: Cache static assets for better performance
|
# Optional: Cache static assets for better performance
|
||||||
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
|
#location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
|
||||||
expires 30d;
|
# expires 30d;
|
||||||
add_header Cache-Control "public";
|
# add_header Cache-Control "public";
|
||||||
}
|
#}
|
||||||
|
|
||||||
error_page 404 /index.html;
|
# error_page 404 /index.html;
|
||||||
|
|
||||||
# put in /etc/nginx/sites-availalble/familytreeapp.conf
|
# put in /etc/nginx/sites-availalble/familytreeapp.conf
|
||||||
# link to enable
|
# link to enable
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
user http;
|
||||||
|
worker_processes auto;
|
||||||
|
worker_cpu_affinity auto;
|
||||||
|
|
||||||
|
#error_log logs/error.log;
|
||||||
|
#error_log logs/error.log notice;
|
||||||
|
#error_log logs/error.log info;
|
||||||
|
|
||||||
|
#pid logs/nginx.pid;
|
||||||
|
|
||||||
|
|
||||||
|
# Load all installed modules
|
||||||
|
#include modules.d/*.conf;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
http {
|
||||||
|
charset utf-8;
|
||||||
|
include mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
types_hash_max_size 4096;
|
||||||
|
client_max_body_size 16M;
|
||||||
|
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
# '$status $body_bytes_sent "$http_referer" '
|
||||||
|
# '"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
#access_log logs/access.log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
#tcp_nopush on;
|
||||||
|
|
||||||
|
#keepalive_timeout 0;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
#gzip on;
|
||||||
|
include modules.d/*.conf;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 81;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
#access_log logs/host.access.log main;
|
||||||
|
|
||||||
|
#kham comment out first
|
||||||
|
#location / {
|
||||||
|
# root /usr/share/nginx/html;
|
||||||
|
# index index.html index.htm;
|
||||||
|
# }
|
||||||
|
|
||||||
|
#error_page 404 /404.html;
|
||||||
|
|
||||||
|
# redirect server error pages to the static page /50x.html
|
||||||
|
#
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
|
||||||
|
#
|
||||||
|
#location ~ \.php$ {
|
||||||
|
# proxy_pass http://127.0.0.1;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
|
||||||
|
#
|
||||||
|
#location ~ \.php$ {
|
||||||
|
# root html;
|
||||||
|
# fastcgi_pass 127.0.0.1:9000;
|
||||||
|
# fastcgi_index index.php;
|
||||||
|
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
|
||||||
|
# include fastcgi_params;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# deny access to .htaccess files, if Apache's document root
|
||||||
|
# concurs with nginx's one
|
||||||
|
#
|
||||||
|
#location ~ /\.ht {
|
||||||
|
# deny all;
|
||||||
|
#}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# another virtual host using mix of IP-, name-, and port-based configuration
|
||||||
|
#
|
||||||
|
#server {
|
||||||
|
# listen 8000;
|
||||||
|
# listen somename:8080;
|
||||||
|
# server_name somename alias another.alias;
|
||||||
|
|
||||||
|
# location / {
|
||||||
|
# root html;
|
||||||
|
# index index.html index.htm;
|
||||||
|
# }
|
||||||
|
#}
|
||||||
|
|
||||||
|
|
||||||
|
# HTTPS server
|
||||||
|
#
|
||||||
|
#server {
|
||||||
|
# listen 443 ssl;
|
||||||
|
# server_name localhost;
|
||||||
|
|
||||||
|
# ssl_certificate cert.pem;
|
||||||
|
# ssl_certificate_key cert.key;
|
||||||
|
|
||||||
|
# ssl_session_cache shared:SSL:1m;
|
||||||
|
# ssl_session_timeout 5m;
|
||||||
|
|
||||||
|
# ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
# ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
# location / {
|
||||||
|
# root html;
|
||||||
|
# index index.html index.htm;
|
||||||
|
# }
|
||||||
|
#}
|
||||||
|
|
||||||
|
}
|
||||||
Generated
+3194
-3674
File diff suppressed because it is too large
Load Diff
+18
-18
@@ -23,35 +23,35 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"packageManager": "npm@11.6.4",
|
"packageManager": "npm@11.6.4",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/common": "^21.0.0",
|
"@angular/common": "^22.0.0",
|
||||||
"@angular/compiler": "^21.0.0",
|
"@angular/compiler": "^22.0.0",
|
||||||
"@angular/core": "^21.0.0",
|
"@angular/core": "^22.0.0",
|
||||||
"@angular/forms": "^21.0.0",
|
"@angular/forms": "^22.0.0",
|
||||||
"@angular/platform-browser": "^21.0.0",
|
"@angular/platform-browser": "^22.0.0",
|
||||||
"@angular/router": "^21.0.0",
|
"@angular/router": "^22.0.0",
|
||||||
"@ngrx/effects": "^21.0.1",
|
"@ngrx/effects": "^22.0.0",
|
||||||
"@ngrx/store": "^21.0.1",
|
"@ngrx/store": "^22.0.0",
|
||||||
"@ngrx/store-devtools": "^21.0.1",
|
"@ngrx/store-devtools": "^22.0.0",
|
||||||
"@primeuix/themes": "^2.0.2",
|
"@openng/optimus-ui": "^2.0.2",
|
||||||
"@tailwindcss/postcss": "^4.1.17",
|
"@tailwindcss/postcss": "^4.1.17",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"primeicons": "^7.0.0",
|
|
||||||
"primeng": "^21.0.1",
|
|
||||||
"rxjs": "~7.8.0",
|
"rxjs": "~7.8.0",
|
||||||
"tailwindcss": "^4.1.17",
|
"tailwindcss": "^4.1.17",
|
||||||
"tailwindcss-primeui": "^0.6.1",
|
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"xlsx": "^0.18.5"
|
"xlsx": "^0.18.5",
|
||||||
|
"@openng/icons": "^1.0.0",
|
||||||
|
"@openng/optimus-ui-themes": "^2.0.2",
|
||||||
|
"@openng/optimus-ui-tailwindcss": "^2.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular/build": "^21.2.7",
|
"@angular/build": "^22.0.0",
|
||||||
"@angular/cli": "^21.2.7",
|
"@angular/cli": "^22.0.0",
|
||||||
"@angular/compiler-cli": "^21.0.0",
|
"@angular/compiler-cli": "^22.0.0",
|
||||||
"@types/file-saver": "^2.0.7",
|
"@types/file-saver": "^2.0.7",
|
||||||
"jsdom": "^27.1.0",
|
"jsdom": "^27.1.0",
|
||||||
"typescript": "~5.9.2",
|
"typescript": "~6.0.0",
|
||||||
"vitest": "^4.0.8"
|
"vitest": "^4.0.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,5 +2,7 @@
|
|||||||
"baseUrl1": "http://192.168.8.188:5015",
|
"baseUrl1": "http://192.168.8.188:5015",
|
||||||
"baseUrl": "http://localhost:5016",
|
"baseUrl": "http://localhost:5016",
|
||||||
"baseUrl_docker": "http://localhost:8080",
|
"baseUrl_docker": "http://localhost:8080",
|
||||||
"attachment": "http://localhost/document/family"
|
"attachment": "http://localhost/document/family",
|
||||||
|
"username": "kham.vilaythong@gmail.com",
|
||||||
|
"prefill_ps": "passwor"
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { ApplicationConfig, provideBrowserGlobalErrorListeners ,
|
import { ApplicationConfig, provideBrowserGlobalErrorListeners ,
|
||||||
provideAppInitializer} from '@angular/core';
|
provideAppInitializer} from '@angular/core';
|
||||||
import { provideRouter, withComponentInputBinding } from '@angular/router';
|
import { provideRouter, withComponentInputBinding } from '@angular/router';
|
||||||
import { providePrimeNG } from 'primeng/config';
|
import { provideOptimus } from '@openng/optimus-ui/config';
|
||||||
import { provideHttpClient, withInterceptors } from '@angular/common/http';
|
import { provideHttpClient, withInterceptors } from '@angular/common/http';
|
||||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
import { ConfirmationService, MessageService } from '@openng/optimus-ui/api';
|
||||||
import { routes } from './app.routes';
|
import { routes } from './app.routes';
|
||||||
import MyPreset from './mythem';
|
import MyPreset from './mythem';
|
||||||
import { JwtInterceptor, ErrorInterceptor, initializeApp } from './shares';
|
import { JwtInterceptor, ErrorInterceptor, initializeApp } from './shares';
|
||||||
@@ -29,13 +29,13 @@ export const appConfig: ApplicationConfig = {
|
|||||||
provideAppInitializer(initializeApp()),
|
provideAppInitializer(initializeApp()),
|
||||||
provideHttpClient(withInterceptors([JwtInterceptor, ErrorInterceptor])),
|
provideHttpClient(withInterceptors([JwtInterceptor, ErrorInterceptor])),
|
||||||
provideRouter(routes, withComponentInputBinding()),
|
provideRouter(routes, withComponentInputBinding()),
|
||||||
providePrimeNG({
|
provideOptimus({
|
||||||
theme: {
|
theme: {
|
||||||
preset: MyPreset,
|
preset: MyPreset,
|
||||||
options: {
|
options: {
|
||||||
cssLayer: {
|
cssLayer: {
|
||||||
name: 'primeng',
|
name: 'optimus',
|
||||||
order: 'theme, base, primeng'
|
order: 'theme, base, optimus'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
import { Component, signal } from '@angular/core';
|
import { Component, signal } from '@angular/core';
|
||||||
import { RouterOutlet } from '@angular/router';
|
import { RouterOutlet } from '@angular/router';
|
||||||
import { ToolbarComponent } from './toolbar/toolbar.component';
|
import { ToolbarComponent } from './toolbar/toolbar.component';
|
||||||
import { ToastModule } from 'primeng/toast';
|
import { ToastModule } from '@openng/optimus-ui/toast';
|
||||||
import { ConfirmDialogModule } from 'primeng/confirmdialog';
|
import { ConfirmDialogModule } from '@openng/optimus-ui/confirmdialog';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
imports: [RouterOutlet,ToastModule,ToolbarComponent,ConfirmDialogModule],
|
imports: [RouterOutlet,ToastModule,ToolbarComponent,ConfirmDialogModule],
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { ChangeDetectorRef, Component, inject, Inject, OnDestroy, OnInit, signal } from '@angular/core';
|
import { ChangeDetectorRef, Component, inject, Inject, OnDestroy, OnInit, signal } from '@angular/core';
|
||||||
import { DynamicDialogModule, DynamicDialogRef ,DynamicDialogConfig} from 'primeng/dynamicdialog';
|
import { DynamicDialogModule, DynamicDialogRef ,DynamicDialogConfig} from '@openng/optimus-ui/dynamicdialog';
|
||||||
|
|
||||||
import { LookupEdit } from '../models';
|
import { LookupEdit } from '../models';
|
||||||
import { UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
import { UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { Subject, Subscription } from 'rxjs';
|
import { Subject, Subscription } from 'rxjs';
|
||||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
import { ConfirmationService, MessageService } from '@openng/optimus-ui/api';
|
||||||
import { LookupService } from '../shares';
|
import { LookupService } from '../shares';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { CheckboxModule } from 'primeng/checkbox';
|
import { CheckboxModule } from '@openng/optimus-ui/checkbox';
|
||||||
import { InputTextModule } from 'primeng/inputtext';
|
import { InputTextModule } from '@openng/optimus-ui/inputtext';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'add-photo',
|
selector: 'add-photo',
|
||||||
imports: [CommonModule, ReactiveFormsModule,
|
imports: [CommonModule, ReactiveFormsModule,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<th>Id</th>
|
<th>Id</th>
|
||||||
<th pSortableColumn="description">Description<p-sortIcon field="description"></p-sortIcon>
|
<th pSortableColumn="description">Description<p-sortIcon field="description"></p-sortIcon>
|
||||||
</th>
|
</th>
|
||||||
|
<th>Photo Type</th>
|
||||||
<th>Action</th>
|
<th>Action</th>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{item.id}}</td>
|
<td>{{item.id}}</td>
|
||||||
<td >{{item.photo}}</td>
|
<td >{{item.photo}}</td>
|
||||||
|
<td>{{item.photoType}}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
<button pButton type="button" icon="pi pi-times"
|
<button pButton type="button" icon="pi pi-times"
|
||||||
|
|||||||
@@ -2,16 +2,16 @@
|
|||||||
import { Component, OnInit, OnDestroy, inject, ChangeDetectorRef, signal, output } from '@angular/core';
|
import { Component, OnInit, OnDestroy, inject, ChangeDetectorRef, signal, output } from '@angular/core';
|
||||||
import { catchError, EMPTY, finalize, Subscription } from 'rxjs';
|
import { catchError, EMPTY, finalize, Subscription } from 'rxjs';
|
||||||
import { CommonUtilities, HttpUtility, LookupService } from '../shares';
|
import { CommonUtilities, HttpUtility, LookupService } from '../shares';
|
||||||
import { DialogService ,DynamicDialogConfig,DynamicDialogModule, DynamicDialogRef} from 'primeng/dynamicdialog';
|
import { DialogService ,DynamicDialogConfig,DynamicDialogModule, DynamicDialogRef} from '@openng/optimus-ui/dynamicdialog';
|
||||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
import { ConfirmationService, MessageService } from '@openng/optimus-ui/api';
|
||||||
import { AddPhoto } from './add.photo';
|
import { AddPhoto } from './add.photo';
|
||||||
import { PersonPhotoDto } from '../models';
|
import { PersonPhotoDto } from '../models';
|
||||||
|
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { TableModule } from 'primeng/table';
|
import { TableModule } from '@openng/optimus-ui/table';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
import { TooltipModule } from 'primeng/tooltip';
|
import { TooltipModule } from '@openng/optimus-ui/tooltip';
|
||||||
import { AuthenticationService } from '../user-services';
|
import { AuthenticationService } from '../user-services';
|
||||||
import { HttpResponse } from '@angular/common/http';
|
import { HttpResponse } from '@angular/common/http';
|
||||||
import { PersonService } from '../person';
|
import { PersonService } from '../person';
|
||||||
@@ -69,11 +69,11 @@ export class PhotoList implements OnInit, OnDestroy {
|
|||||||
downloadAttachment(id: number): void {
|
downloadAttachment(id: number): void {
|
||||||
//GetReportFile
|
//GetReportFile
|
||||||
|
|
||||||
let typeofCall = "personId_" + id.toString();
|
let typeofCall = "personPhotoId_" + id.toString();
|
||||||
|
|
||||||
let criteria:any ={id, fileName:''};
|
let criteria: any = { id };
|
||||||
this.downloadFile.set(false);
|
this.downloadFile.set(false);
|
||||||
this.http.getFileResponse("api/FileUpload/downloadPersonPhoto", criteria).pipe(
|
this.http.getFileResponse("api/FileUpload/DownloadPersonPhotoById", criteria).pipe(
|
||||||
catchError(err => {
|
catchError(err => {
|
||||||
console.error(err.message);
|
console.error(err.message);
|
||||||
return EMPTY;
|
return EMPTY;
|
||||||
@@ -128,7 +128,7 @@ doRemove(id: number): void {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const deletepersonPhoto$ = this.personService.deletePersonPhotoFile(id);
|
const deletepersonPhoto$ = this.personService.deletePersonPhotoFileById(id);
|
||||||
this.subscription.add(deletepersonPhoto$.subscribe(
|
this.subscription.add(deletepersonPhoto$.subscribe(
|
||||||
{
|
{
|
||||||
next: x => {
|
next: x => {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Component, inject, OnInit } from '@angular/core';
|
import { Component, inject, OnInit } from '@angular/core';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
import { FileUploadEvent, FileUploadModule } from 'primeng/fileupload';
|
import { FileUploadEvent, FileUploadModule } from '@openng/optimus-ui/fileupload';
|
||||||
import { MessageService } from 'primeng/api';
|
import { MessageService } from '@openng/optimus-ui/api';
|
||||||
import { FileUpload } from 'primeng/fileupload';
|
import { FileUpload } from '@openng/optimus-ui/fileupload';
|
||||||
import { ToastModule } from 'primeng/toast';
|
import { ToastModule } from '@openng/optimus-ui/toast';
|
||||||
import { AppSettingService } from '../shares';
|
import { AppSettingService } from '../shares';
|
||||||
/*
|
/*
|
||||||
interface UploadEvent {
|
interface UploadEvent {
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ import { first } from 'rxjs/operators';
|
|||||||
|
|
||||||
import { AuthenticationService } from '../user-services';
|
import { AuthenticationService } from '../user-services';
|
||||||
|
|
||||||
import { ConfirmationService } from 'primeng/api';
|
import { ConfirmationService } from '@openng/optimus-ui/api';
|
||||||
import { Subject, Subscription } from 'rxjs';
|
import { Subject, Subscription } from 'rxjs';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { CardModule } from 'primeng/card';
|
import { CardModule } from '@openng/optimus-ui/card';
|
||||||
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
|
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
import { InputTextModule } from 'primeng/inputtext';
|
import { InputTextModule } from '@openng/optimus-ui/inputtext';
|
||||||
|
|
||||||
import { Utils } from '../shares';
|
import { AppSettingService, Utils } from '../shares';
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './login.html',
|
templateUrl: './login.html',
|
||||||
styleUrl: './login.css',
|
styleUrl: './login.css',
|
||||||
@@ -29,6 +29,7 @@ export class Login implements OnInit, OnDestroy {
|
|||||||
router = inject(Router);
|
router = inject(Router);
|
||||||
authenticationService = inject(AuthenticationService);
|
authenticationService = inject(AuthenticationService);
|
||||||
formBuilder = inject(FormBuilder);
|
formBuilder = inject(FormBuilder);
|
||||||
|
private appSetting =inject(AppSettingService);
|
||||||
loading = false;
|
loading = false;
|
||||||
homeUrl = "/person";
|
homeUrl = "/person";
|
||||||
submitted = false;
|
submitted = false;
|
||||||
@@ -40,10 +41,11 @@ export class Login implements OnInit, OnDestroy {
|
|||||||
private subscription: Subscription = new Subscription();
|
private subscription: Subscription = new Subscription();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
const default_us = this.appSetting.appSetting.username;
|
||||||
|
const pass = this.appSetting.appSetting.prefill_ps;
|
||||||
this.loginForm = this.formBuilder.group({
|
this.loginForm = this.formBuilder.group({
|
||||||
username: ['kham.vilaythong@gmail.com', Validators.required],
|
username: [default_us, Validators.required],
|
||||||
password: ['password', Validators.required],
|
password: [pass, Validators.required],
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ export enum mState {
|
|||||||
Modified = 1,
|
Modified = 1,
|
||||||
New =2,
|
New =2,
|
||||||
};
|
};
|
||||||
|
export enum enumPhoto {
|
||||||
|
Profile = 1,
|
||||||
|
Other = 2
|
||||||
|
}
|
||||||
export enum userRole {
|
export enum userRole {
|
||||||
Normal = 1,
|
Normal = 1,
|
||||||
Admin = 2,
|
Admin = 2,
|
||||||
|
|||||||
+29
-38
@@ -1,51 +1,41 @@
|
|||||||
|
|
||||||
|
|
||||||
//mypreset.ts
|
//mypreset.ts
|
||||||
import { definePreset } from '@primeuix/themes';
|
import { definePreset } from '@openng/optimus-ui-themes';
|
||||||
import Aura from '@primeuix/themes/aura';
|
import Aura from '@openng/optimus-ui-themes/aura';
|
||||||
import { primitive } from '@primeuix/themes/aura/base';
|
|
||||||
|
|
||||||
const MyPreset = definePreset(Aura, {
|
const MyPreset = definePreset(Aura, {
|
||||||
semantic: {
|
semantic: {
|
||||||
colorScheme: {
|
primary: {
|
||||||
primitive: {
|
50: '{blue.50}',
|
||||||
cyan: {
|
100: '{blue.100}',
|
||||||
50: '{cyan.50}',
|
200: '{blue.200}',
|
||||||
100: '{cyan.100}',
|
300: '{blue.300}',
|
||||||
200: '{cyan.200}',
|
400: '{blue.400}',
|
||||||
300: '{cyan.300}',
|
500: '{blue.500}',
|
||||||
400: '{cyan.400}',
|
600: '{blue.600}',
|
||||||
500: '{cyan.500}',
|
700: '{blue.700}',
|
||||||
}
|
800: '{blue.800}',
|
||||||
|
900: '{blue.900}',
|
||||||
},
|
950: '{blue.950}'
|
||||||
primary: {
|
|
||||||
50: '{zinc.50}',
|
|
||||||
100: '{zinc.100}',
|
|
||||||
200: '{zinc.200}',
|
|
||||||
300: '{zinc.300}',
|
|
||||||
400: '{zinc.400}',
|
|
||||||
500: '{zinc.500}',
|
|
||||||
600: '{zinc.600}',
|
|
||||||
700: '{zinc.700}',
|
|
||||||
800: '{zinc.800}',
|
|
||||||
900: '{zinc.900}',
|
|
||||||
950: '{zinc.950}'
|
|
||||||
},
|
},
|
||||||
|
colorScheme: {
|
||||||
|
|
||||||
|
|
||||||
light: {
|
light: {
|
||||||
surface: {
|
surface: {
|
||||||
0: '#ffffff',
|
0: '#ffffff',
|
||||||
50: '{zinc.50}',
|
50: '{blue.50}',
|
||||||
100: '{zinc.100}',
|
100: '{blue.100}',
|
||||||
200: '{zinc.200}',
|
200: '{blue.200}',
|
||||||
300: '{zinc.300}',
|
300: '{blue.300}',
|
||||||
400: '{zinc.400}',
|
400: '{blue.400}',
|
||||||
500: '{zinc.500}',
|
500: '{blue.500}',
|
||||||
600: '{zinc.600}',
|
600: '{blue.600}',
|
||||||
700: '{zinc.700}',
|
700: '{blue.700}',
|
||||||
800: '{zinc.800}',
|
800: '{blue.800}',
|
||||||
900: '{zinc.900}',
|
900: '{blue.900}',
|
||||||
950: '{zinc.950}'
|
950: '{blue.950}'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dark: {
|
dark: {
|
||||||
@@ -65,6 +55,7 @@ const MyPreset = definePreset(Aura, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
import { Component, OnInit, OnDestroy, inject, ChangeDetectorRef, signal} from '@angular/core';
|
import { Component, OnInit, OnDestroy, inject, ChangeDetectorRef, signal} from '@angular/core';
|
||||||
|
|
||||||
import { StaffView ,StaffSearch, Person, RelationShip } from '../models';
|
import { StaffView ,StaffSearch, Person, RelationShip } from '../models';
|
||||||
import { OrganizationChartModule } from 'primeng/organizationchart';
|
import { OrganizationChartModule } from '@openng/optimus-ui/organizationchart';
|
||||||
|
|
||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { PersonService } from './person.service';
|
import { PersonService } from './person.service';
|
||||||
import { TableModule } from 'primeng/table';
|
import { TableModule } from '@openng/optimus-ui/table';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
import { TreeNode } from 'primeng/api';
|
import { TreeNode } from '@openng/optimus-ui/api';
|
||||||
import { InputTextModule } from 'primeng/inputtext';
|
import { InputTextModule } from '@openng/optimus-ui/inputtext';
|
||||||
import { DialogService, DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
|
import { DialogService, DynamicDialogConfig, DynamicDialogRef } from '@openng/optimus-ui/dynamicdialog';
|
||||||
import { PersonEdit } from './person.edit';
|
import { PersonEdit } from './person.edit';
|
||||||
import { MessageService } from 'primeng/api';
|
import { MessageService } from '@openng/optimus-ui/api';
|
||||||
import { TreeModule, TreeNodeDoubleClickEvent, TreeNodeSelectEvent } from 'primeng/tree';
|
import { TreeModule, TreeNodeDoubleClickEvent, TreeNodeSelectEvent } from '@openng/optimus-ui/tree';
|
||||||
import { Utils } from '../shares';
|
import { Utils } from '../shares';
|
||||||
import { PopoverModule } from 'primeng/popover';
|
import { PopoverModule } from '@openng/optimus-ui/popover';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'family-orga',
|
selector: 'family-orga',
|
||||||
@@ -64,7 +64,7 @@ export class FamilyOrga implements OnInit, OnDestroy{
|
|||||||
{
|
{
|
||||||
expanded: true,
|
expanded: true,
|
||||||
type: 'person',
|
type: 'person',
|
||||||
styleClass: 'bg-indigo-500 text-white',
|
styleClass: 'bg-blue-500 text-white',
|
||||||
data: {
|
data: {
|
||||||
image: 'https://primefaces.org/cdn/primeng/images/demo/avatar/amyelsner.png',
|
image: 'https://primefaces.org/cdn/primeng/images/demo/avatar/amyelsner.png',
|
||||||
name: 'Amy Elsner',
|
name: 'Amy Elsner',
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
import { Component, OnInit, OnDestroy, inject, ChangeDetectorRef, signal} from '@angular/core';
|
import { Component, OnInit, OnDestroy, inject, ChangeDetectorRef, signal} from '@angular/core';
|
||||||
|
|
||||||
import { StaffView ,StaffSearch, Person } from '../models';
|
import { StaffView ,StaffSearch, Person } from '../models';
|
||||||
import { OrganizationChartModule } from 'primeng/organizationchart';
|
import { OrganizationChartModule } from '@openng/optimus-ui/organizationchart';
|
||||||
|
|
||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { PersonService } from './person.service';
|
import { PersonService } from './person.service';
|
||||||
import { AuthenticationService } from '../user-services';
|
import { AuthenticationService } from '../user-services';
|
||||||
import { TableModule } from 'primeng/table';
|
import { TableModule } from '@openng/optimus-ui/table';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
import { TreeNode } from 'primeng/api';
|
import { TreeNode } from '@openng/optimus-ui/api';
|
||||||
import { InputTextModule } from 'primeng/inputtext';
|
import { InputTextModule } from '@openng/optimus-ui/inputtext';
|
||||||
import { DialogService } from 'primeng/dynamicdialog';
|
import { DialogService } from '@openng/optimus-ui/dynamicdialog';
|
||||||
import { PersonEdit } from './person.edit';
|
import { PersonEdit } from './person.edit';
|
||||||
import { MessageService } from 'primeng/api';
|
import { MessageService } from '@openng/optimus-ui/api';
|
||||||
import { CheckboxModule } from 'primeng/checkbox';
|
import { CheckboxModule } from '@openng/optimus-ui/checkbox';
|
||||||
import { TreeModule, TreeNodeDoubleClickEvent, TreeNodeSelectEvent } from 'primeng/tree';
|
import { TreeModule, TreeNodeDoubleClickEvent, TreeNodeSelectEvent } from '@openng/optimus-ui/tree';
|
||||||
import { Utils } from '../shares';
|
import { Utils } from '../shares';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|||||||
@@ -8,17 +8,17 @@ import { Subscription } from 'rxjs';
|
|||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { PersonService } from './person.service';
|
import { PersonService } from './person.service';
|
||||||
import { AuthenticationService } from '../user-services';
|
import { AuthenticationService } from '../user-services';
|
||||||
import { Table, TableModule } from 'primeng/table';
|
import { Table, TableModule } from '@openng/optimus-ui/table';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
import { InputTextModule } from 'primeng/inputtext';
|
import { InputTextModule } from '@openng/optimus-ui/inputtext';
|
||||||
import { DialogService } from 'primeng/dynamicdialog';
|
import { DialogService } from '@openng/optimus-ui/dynamicdialog';
|
||||||
import { PersonEdit } from './person.edit';
|
import { PersonEdit } from './person.edit';
|
||||||
import { ConfirmationService, MenuItem, MessageService } from 'primeng/api';
|
import { ConfirmationService, MenuItem, MessageService } from '@openng/optimus-ui/api';
|
||||||
import { IconFieldModule } from 'primeng/iconfield';
|
import { IconFieldModule } from '@openng/optimus-ui/iconfield';
|
||||||
import { InputIconModule } from 'primeng/inputicon';
|
import { InputIconModule } from '@openng/optimus-ui/inputicon';
|
||||||
import { Menu, MenuModule } from 'primeng/menu';
|
import { Menu, MenuModule } from '@openng/optimus-ui/menu';
|
||||||
import { FamilyOrga } from './family.orga';
|
import { FamilyOrga } from './family.orga';
|
||||||
|
|
||||||
import { saveAs } from 'file-saver';
|
import { saveAs } from 'file-saver';
|
||||||
|
|||||||
@@ -1,27 +1,28 @@
|
|||||||
import { ChangeDetectorRef, Component, inject, OnDestroy, OnInit, signal, ViewChild } from '@angular/core';
|
import { ChangeDetectorRef, Component, inject, OnDestroy, OnInit, signal, ViewChild } from '@angular/core';
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
import {DialogService, DynamicDialogRef} from 'primeng/dynamicdialog';
|
import {DialogService, DynamicDialogRef} from '@openng/optimus-ui/dynamicdialog';
|
||||||
import {DynamicDialogConfig} from 'primeng/dynamicdialog';
|
import {DynamicDialogConfig} from '@openng/optimus-ui/dynamicdialog';
|
||||||
import { FormControl, ReactiveFormsModule, UntypedFormBuilder, Validators } from '@angular/forms';
|
import { FormControl, ReactiveFormsModule, UntypedFormBuilder, Validators } from '@angular/forms';
|
||||||
import { Subject, Subscription} from 'rxjs';
|
import { Subject, Subscription} from 'rxjs';
|
||||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
import { ConfirmationService, MessageService } from '@openng/optimus-ui/api';
|
||||||
import { DatePickerModule } from 'primeng/datepicker';
|
import { DatePickerModule } from '@openng/optimus-ui/datepicker';
|
||||||
import { Code, RelationShipView, Person, mState, RelationShip, PersonPhotoDto} from '../models';
|
import { Code, RelationShipView, Person, mState, RelationShip, PersonPhotoDto, enumPhoto } from '../models';
|
||||||
import { AppSettingService, LookupService, Utils } from '../shares';
|
import { AppSettingService, LookupService, Utils } from '../shares';
|
||||||
import { PersonService } from './person.service';
|
import { PersonService } from './person.service';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
import { SelectModule } from 'primeng/select';
|
import { SelectModule } from '@openng/optimus-ui/select';
|
||||||
import { CheckboxModule } from 'primeng/checkbox';
|
import { CheckboxModule } from '@openng/optimus-ui/checkbox';
|
||||||
import { InputTextModule } from 'primeng/inputtext';
|
import { InputTextModule } from '@openng/optimus-ui/inputtext';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { HttpEvent } from '@angular/common/http';
|
import { HttpEvent } from '@angular/common/http';
|
||||||
import { TableModule } from 'primeng/table';
|
import { TableModule } from '@openng/optimus-ui/table';
|
||||||
import { Pickperson } from '../pickperson/pickperson';
|
import { Pickperson } from '../pickperson/pickperson';
|
||||||
import { ImageDisplayComponent } from '../pickperson/image.display';
|
import { ImageDisplayComponent } from '../pickperson/image.display';
|
||||||
import { TooltipModule } from 'primeng/tooltip';
|
import { TooltipModule } from '@openng/optimus-ui/tooltip';
|
||||||
import { AutoFocusModule } from 'primeng/autofocus';
|
import { AutoFocusModule } from '@openng/optimus-ui/autofocus';
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
import { PhotoList } from '../attachphoto/photolist';
|
import { PhotoList } from '../attachphoto/photolist';
|
||||||
|
import { InputNumberDesignTokens } from '@openng/optimus-ui-themes/types/inputnumber';
|
||||||
|
|
||||||
export interface FileUploadEvent {
|
export interface FileUploadEvent {
|
||||||
originalEvent: HttpEvent<any>;
|
originalEvent: HttpEvent<any>;
|
||||||
@@ -190,9 +191,9 @@ doDeleteFile(): void {
|
|||||||
this.profileFile = null;
|
this.profileFile = null;
|
||||||
}
|
}
|
||||||
doDeleteImage(fileName:string) : void {
|
doDeleteImage(fileName:string) : void {
|
||||||
const familyId = this.adminuserForm.value.id;
|
const personId = this.adminuserForm.value.id;
|
||||||
const data = { fileName, familyId };
|
const photoType = enumPhoto.Profile;
|
||||||
const delete$ = this.personService.deleteUploadFile(data);
|
const delete$ = this.personService.deletePersonPhotoFile(personId, photoType);
|
||||||
this.subscription.add(delete$.subscribe(
|
this.subscription.add(delete$.subscribe(
|
||||||
{
|
{
|
||||||
next: x => {
|
next: x => {
|
||||||
@@ -306,7 +307,9 @@ get isFieldsChange() {
|
|||||||
doViewImage(imageName:string): void {
|
doViewImage(imageName:string): void {
|
||||||
const ref = this.dialogService.open(ImageDisplayComponent, {
|
const ref = this.dialogService.open(ImageDisplayComponent, {
|
||||||
data: {
|
data: {
|
||||||
imageName,
|
imageName,
|
||||||
|
personId: this._id,
|
||||||
|
photyType: enumPhoto.Profile
|
||||||
},
|
},
|
||||||
header: 'View Image',
|
header: 'View Image',
|
||||||
draggable: true,
|
draggable: true,
|
||||||
@@ -358,7 +361,7 @@ assignValue(item:Person): void {
|
|||||||
}
|
}
|
||||||
if (item.image && item.image.length > 0)
|
if (item.image && item.image.length > 0)
|
||||||
{
|
{
|
||||||
this.loadImage(item.image);
|
this.loadImage(item.image, item.id, enumPhoto.Profile);
|
||||||
}
|
}
|
||||||
// disable use false//true for not disable.
|
// disable use false//true for not disable.
|
||||||
this.subChanged$.next(true);
|
this.subChanged$.next(true);
|
||||||
@@ -367,8 +370,10 @@ assignValue(item:Person): void {
|
|||||||
// convenience getter for easy access in form fields
|
// convenience getter for easy access in form fields
|
||||||
get f() { return this.adminuserForm.controls;}
|
get f() { return this.adminuserForm.controls;}
|
||||||
|
|
||||||
loadImage(fileName: string| null): void {
|
loadImage(fileName: string | null,
|
||||||
const download = this.personService.downloadFile(fileName!);
|
personId: number, photoType: number): void {
|
||||||
|
if (fileName) {
|
||||||
|
const download = this.personService.downloadPersonPhoto64(fileName, personId, photoType);
|
||||||
this.subscription.add(download.subscribe({
|
this.subscription.add(download.subscribe({
|
||||||
next: x => {
|
next: x => {
|
||||||
if (x.statusCode == 1)
|
if (x.statusCode == 1)
|
||||||
@@ -384,8 +389,10 @@ assignValue(item:Person): void {
|
|||||||
},
|
},
|
||||||
error: e => console.error("error in download image", e)
|
error: e => console.error("error in download image", e)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
displayIamge64(baseImage: string): void
|
}
|
||||||
|
|
||||||
|
displayIamge64(baseImage: string): void
|
||||||
{
|
{
|
||||||
const changeUrl = (this.sanitizer.bypassSecurityTrustResourceUrl(baseImage) as any).changingThisBreaksApplicationSecurity;
|
const changeUrl = (this.sanitizer.bypassSecurityTrustResourceUrl(baseImage) as any).changingThisBreaksApplicationSecurity;
|
||||||
console.log('this is bypassSecurityTrustResourceUrl', changeUrl);
|
console.log('this is bypassSecurityTrustResourceUrl', changeUrl);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { Staff,StaffSearch, StaffView, ResultModel,ConfigureUrl,ResetPassword, Person, PersonContainer, RelationShip } from '../models';
|
import { Staff,StaffSearch, StaffView, ResultModel,ConfigureUrl,ResetPassword, Person, PersonContainer, RelationShip } from '../models';
|
||||||
import { AppSettingService } from '../shares';
|
import { AppSettingService } from '../shares';
|
||||||
import { TreeNode } from 'primeng/api';
|
import { TreeNode } from '@openng/optimus-ui/api';
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class PersonService {
|
export class PersonService {
|
||||||
@@ -77,33 +77,60 @@ export class PersonService {
|
|||||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.personUrl + "/UploadImage";
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.personUrl + "/UploadImage";
|
||||||
return this.http.post<ResultModel<string>>(baseUrl, data);
|
return this.http.post<ResultModel<string>>(baseUrl, data);
|
||||||
}
|
}
|
||||||
downloadFile(imageName: string): Observable<ResultModel<string>> {
|
downloadFile_dontusethis(imageName: string, personId: number,
|
||||||
|
photoType: number): Observable<ResultModel<string>> {
|
||||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/DownloadFile";
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/DownloadFile";
|
||||||
const data = {
|
const data = {
|
||||||
fileName: imageName
|
fileName: imageName,
|
||||||
|
id: personId,
|
||||||
|
photoType
|
||||||
};
|
};
|
||||||
return this.http.post<ResultModel<string>>(baseUrl, data);
|
return this.http.post<ResultModel<string>>(baseUrl, data);
|
||||||
}
|
}
|
||||||
deleteUploadFile(data: any): Observable<ResultModel<number>> {
|
deleteUploadFile_dotnotuse(data: any): Observable<ResultModel<number>> {
|
||||||
//data ={filename};
|
//data ={filename};
|
||||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.personUrl + "/DeleteUploadFile";
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.personUrl + "/DeleteUploadFile";
|
||||||
return this.http.post<ResultModel<number>>(baseUrl, data);
|
return this.http.post<ResultModel<number>>(baseUrl, data);
|
||||||
}
|
}
|
||||||
deletePersonPhotoFile(id: number): Observable<ResultModel<number>> {
|
deletePersonPhotoFile(personId: number, photoType: number): Observable<ResultModel<number>> {
|
||||||
const data ={id, fileName:''};
|
const data = {
|
||||||
|
id: personId,
|
||||||
|
fileName: '',
|
||||||
|
photoType
|
||||||
|
};
|
||||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/DeletePersonPhoto";
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/DeletePersonPhoto";
|
||||||
return this.http.post<ResultModel<number>>(baseUrl, data);
|
return this.http.post<ResultModel<number>>(baseUrl, data);
|
||||||
}
|
}
|
||||||
|
deletePersonPhotoFileById(id: number): Observable<ResultModel<number>> {
|
||||||
|
const data = {
|
||||||
|
id
|
||||||
|
};
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/DeletePersonPhotoById";
|
||||||
|
return this.http.post<ResultModel<number>>(baseUrl, data);
|
||||||
|
}
|
||||||
savePersonPhotoList(data:FormData): Observable<ResultModel<number>> {
|
savePersonPhotoList(data:FormData): Observable<ResultModel<number>> {
|
||||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/SavePersonPhoto";
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/SavePersonPhoto";
|
||||||
return this.http.post<ResultModel<number>>(baseUrl, data);
|
return this.http.post<ResultModel<number>>(baseUrl, data);
|
||||||
}
|
}
|
||||||
downloadPersonPhoto(id: number): Observable<ResultModel<string>> {
|
|
||||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/DownloadPersonPhoto";
|
downloadPersonPhoto64(imageName: string, personId: number,
|
||||||
|
photoType: number): Observable<ResultModel<string>> {
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/DownloadPersonPhoto64";
|
||||||
const data = {
|
const data = {
|
||||||
id,
|
id: personId,
|
||||||
fileName: ''
|
photoType,
|
||||||
|
fileName: imageName
|
||||||
};
|
};
|
||||||
return this.http.post<ResultModel<string>>(baseUrl, data);
|
return this.http.post<ResultModel<string>>(baseUrl, data);
|
||||||
}
|
}
|
||||||
|
downloadPersonPhoto(imageName: string, personId: number,
|
||||||
|
photoType: number): Observable<any> {
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/DownloadPersonPhoto";
|
||||||
|
const data = {
|
||||||
|
id: personId,
|
||||||
|
photoType,
|
||||||
|
fileName: imageName
|
||||||
|
};
|
||||||
|
return this.http.post<any>(baseUrl, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import { PersonService } from '../person';
|
|||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
|
import { DynamicDialogConfig, DynamicDialogRef } from '@openng/optimus-ui/dynamicdialog';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-image-display',
|
selector: 'app-image-display',
|
||||||
@@ -27,12 +27,14 @@ export class ImageDisplayComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|
||||||
const imageName = this.config.data.imageName;
|
const imageName = this.config.data.imageName;
|
||||||
this.loadImage(imageName);
|
const personId = this.config.data.personId;
|
||||||
|
const photoType = this.config.data.photyType;
|
||||||
|
this.loadImage(imageName, personId, photoType);
|
||||||
|
|
||||||
}
|
}
|
||||||
loadImage(fileName: string| null): void {
|
loadImage(fileName: string | null, personId: number, photoType: number): void {
|
||||||
const download = this.personService.downloadFile(fileName!);
|
const download = this.personService.downloadPersonPhoto64(fileName!, personId, photoType);
|
||||||
this.subscription.add(download.subscribe({
|
this.subscription.add(download.subscribe({
|
||||||
next: x => {
|
next: x => {
|
||||||
if (x.statusCode == 1)
|
if (x.statusCode == 1)
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { Component, OnDestroy, OnInit, signal, ViewChild } from '@angular/core';
|
import { Component, OnDestroy, OnInit, signal, ViewChild } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { Table, TableModule } from 'primeng/table';
|
import { Table, TableModule } from '@openng/optimus-ui/table';
|
||||||
import { Person } from '../models';
|
import { Person } from '../models';
|
||||||
import { IconFieldModule } from 'primeng/iconfield';
|
import { IconFieldModule } from '@openng/optimus-ui/iconfield';
|
||||||
import { InputIconModule } from 'primeng/inputicon';
|
import { InputIconModule } from '@openng/optimus-ui/inputicon';
|
||||||
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
|
import { DynamicDialogConfig, DynamicDialogRef } from '@openng/optimus-ui/dynamicdialog';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
import { InputTextModule } from 'primeng/inputtext';
|
import { InputTextModule } from '@openng/optimus-ui/inputtext';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-pickperson',
|
selector: 'app-pickperson',
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { Person, User, userRole } from "../models"
|
import { Person, User, userRole } from "../models"
|
||||||
import { TreeNode } from "primeng/api";
|
import { TreeNode } from "@openng/optimus-ui/api";
|
||||||
|
|
||||||
type MyProName = "fatherId" | "motherId";
|
type MyProName = "fatherId" | "motherId";
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ import { Subscription } from 'rxjs';
|
|||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { StaffService } from './staff.service';
|
import { StaffService } from './staff.service';
|
||||||
import { AuthenticationService } from '../user-services';
|
import { AuthenticationService } from '../user-services';
|
||||||
import { TableModule } from 'primeng/table';
|
import { TableModule } from '@openng/optimus-ui/table';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
import { InputTextModule } from 'primeng/inputtext';
|
import { InputTextModule } from '@openng/optimus-ui/inputtext';
|
||||||
import { selectStaffLoaded,selectStaff } from '../state/staff.selectors';
|
import { selectStaffLoaded,selectStaff } from '../state/staff.selectors';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ import { Component, inject, input, numberAttribute, OnDestroy, OnInit } from '@a
|
|||||||
import { Router, ActivatedRoute } from '@angular/router';
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
import { ReactiveFormsModule, UntypedFormBuilder, Validators } from '@angular/forms';
|
import { ReactiveFormsModule, UntypedFormBuilder, Validators } from '@angular/forms';
|
||||||
import { Subject, Subscription} from 'rxjs';
|
import { Subject, Subscription} from 'rxjs';
|
||||||
import { MessageService } from 'primeng/api';
|
import { MessageService } from '@openng/optimus-ui/api';
|
||||||
|
|
||||||
import {Staff, Code, userRole} from '../models';
|
import {Staff, Code, userRole} from '../models';
|
||||||
import { LookupService, Utils } from '../shares';
|
import { LookupService, Utils } from '../shares';
|
||||||
import { StaffService } from './staff.service';
|
import { StaffService } from './staff.service';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
import { SelectModule } from 'primeng/select';
|
import { SelectModule } from '@openng/optimus-ui/select';
|
||||||
import { CheckboxModule } from 'primeng/checkbox';
|
import { CheckboxModule } from '@openng/optimus-ui/checkbox';
|
||||||
import { InputTextModule } from 'primeng/inputtext';
|
import { InputTextModule } from '@openng/optimus-ui/inputtext';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: 'staff.edit.component.html',
|
templateUrl: 'staff.edit.component.html',
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
|||||||
import { Router, ActivatedRoute } from '@angular/router';
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
import { FormsModule, ReactiveFormsModule, UntypedFormBuilder, Validators } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule, UntypedFormBuilder, Validators } from '@angular/forms';
|
||||||
import { Subject, Subscription} from 'rxjs';
|
import { Subject, Subscription} from 'rxjs';
|
||||||
import { MessageService } from 'primeng/api';
|
import { MessageService } from '@openng/optimus-ui/api';
|
||||||
|
|
||||||
import {Staff, Code, userRole, ResetPassword} from '../models';
|
import {Staff, Code, userRole, ResetPassword} from '../models';
|
||||||
import { LookupService, Utils } from '../shares';
|
import { LookupService, Utils } from '../shares';
|
||||||
import { StaffService } from './staff.service';
|
import { StaffService } from './staff.service';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from '@openng/optimus-ui/button';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: 'staff.pass.component.html',
|
templateUrl: 'staff.pass.component.html',
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
@if (currentUserS() && isAuth)
|
@if (currentUserS() && isAuth == true)
|
||||||
{
|
{
|
||||||
<div class="flex flex-column justify-between md:flex-row rounded" style="background-color:transparent">
|
<div class="flex flex-column justify-between md:flex-row rounded" style="background-color:transparent">
|
||||||
<div style="margin-top:5px;padding-right:35px; cursor: pointer;width:400px;">
|
<div style="margin-top:5px;padding-right:35px; cursor: pointer;width:400px;">
|
||||||
<img (click)="onHome()" src="images/application_image.png" alt="Banner" style="height:80px;width:100%" />
|
<img (click)="onHome()" src="images/application_image.png" alt="Banner" style="height:80px;width:100%" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end items-end flex-row">
|
<div class="flex justify-end items-end flex-row">
|
||||||
<div class="flex-column">
|
<div class="flex-column">
|
||||||
<label class=" flex justify-end items-end mr-1 mb-2 myname">{{loginUser}}</label>
|
<label class=" flex justify-end items-end mr-1 mb-2 myname">{{loginUser}}</label>
|
||||||
<div>
|
<div>
|
||||||
<span class="md:hidden flex justify-end"> <!--hidden on md screen show on small-->
|
|
||||||
<button type="button" pButton icon="pi pi-align-justify" (click)="onemenu.toggle($event);"></button>
|
|
||||||
<p-menu #onemenu [popup]="true" [model]="oneMenu"></p-menu>
|
|
||||||
</span>
|
|
||||||
<span class="hidden md:inline-flex"> <!--hidden when small screen-->
|
<span class="hidden md:inline-flex"> <!--hidden when small screen-->
|
||||||
<p-buttonGroup >
|
<p-buttonGroup >
|
||||||
<button type="button" pButton icon="pi pi-slack" label="Home" (click)="onHome()"
|
<button type="button" pButton icon="pi pi-slack" label="Home" (click)="onHome()"
|
||||||
@@ -38,4 +36,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!--put in the left new row if in mobile not much room-->
|
||||||
|
<span class="md:hidden flex justify-start"> <!--hidden on md screen show on small-->
|
||||||
|
<button type="button" pButton icon="pi pi-align-justify" (click)="onemenu.toggle($event);"></button>
|
||||||
|
<p-menu #onemenu [popup]="true" [model]="oneMenu"></p-menu>
|
||||||
|
</span>
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Component, OnInit, OnDestroy, effect, computed, Signal, } from '@angular/core';
|
import { Component, OnInit, OnDestroy, effect, computed, Signal, } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from '@openng/optimus-ui/api';
|
||||||
import { MenuModule } from 'primeng/menu';
|
import { MenuModule } from '@openng/optimus-ui/menu';
|
||||||
import { ButtonModule} from 'primeng/button';
|
import { ButtonModule} from '@openng/optimus-ui/button';
|
||||||
import { ButtonGroupModule } from 'primeng/buttongroup';
|
import { ButtonGroupModule } from '@openng/optimus-ui/buttongroup';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { AuthenticationService } from '../user-services';
|
import { AuthenticationService } from '../user-services';
|
||||||
import { Utils } from '../shares';
|
import { Utils } from '../shares';
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
/* You can add global styles to this file, and also import other style files */
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@plugin "tailwindcss-primeui";
|
@plugin "@openng/optimus-ui-tailwindcss";
|
||||||
@import "primeicons/primeicons.css";
|
@import "@openng/icons/openng-icons.css";
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"experimentalDecorators": true,
|
|
||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"module": "preserve"
|
"module": "preserve"
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { HttpInterceptorFn } from '@angular/common/http';
|
||||||
|
|
||||||
|
export const credentialsInterceptor: HttpInterceptorFn = (req, next) => {
|
||||||
|
// Clone the request to add the withCredentials property
|
||||||
|
const clonedRequest = req.clone({
|
||||||
|
withCredentials: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return next(clonedRequest);
|
||||||
|
};
|
||||||
|
|
||||||
|
typescriptimport { provideHttpClient, withInterceptors } from '@angular/common/http';
|
||||||
|
import { credentialsInterceptor } from './credentials.interceptor';
|
||||||
|
|
||||||
|
export const appConfig: ApplicationConfig = {
|
||||||
|
providers: [
|
||||||
|
provideHttpClient(
|
||||||
|
withInterceptors([credentialsInterceptor]) // Register it here
|
||||||
|
)
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
2. Individual Request ConfigurationIf you only want to send cookies to specific endpoints,
|
||||||
|
pass the withCredentials option directly inside your service.
|
||||||
|
|
||||||
|
typescriptimport { HttpClient } from '@angular/common/http';
|
||||||
|
import { inject, Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class ApiService {
|
||||||
|
private http = inject(HttpClient);
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
return this.http.get('https://your-api-domain.com', {
|
||||||
|
withCredentials: true // Enables cookies for this request only
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user