check in display image using api now
This commit is contained in:
@@ -22,7 +22,7 @@ public class FileUploadController : ControllerBase
|
|||||||
_config = config;
|
_config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("UploadFile")]
|
[HttpPost("[action]")]
|
||||||
public async Task<IActionResult> UploadFile(IFormFile file)
|
public async Task<IActionResult> UploadFile(IFormFile file)
|
||||||
{
|
{
|
||||||
List<CodeDto<string>> output = new ();
|
List<CodeDto<string>> output = new ();
|
||||||
@@ -36,7 +36,7 @@ public class FileUploadController : ControllerBase
|
|||||||
|
|
||||||
// Define the upload directory
|
// Define the upload directory
|
||||||
// var uploadsFolder = Path.Combine(_hostingEnvironment.WebRootPath, "uploads");
|
// var uploadsFolder = Path.Combine(_hostingEnvironment.WebRootPath, "uploads");
|
||||||
string importFolder = _config.GetValue<string>("ImportFolder");
|
string importFolder = _config.GetValue<string>("AppSettings:ImportFolder");
|
||||||
var uploadsFolder = Path.Combine(_hostingEnvironment.ContentRootPath, importFolder);
|
var uploadsFolder = Path.Combine(_hostingEnvironment.ContentRootPath, importFolder);
|
||||||
if (!Directory.Exists(uploadsFolder))
|
if (!Directory.Exists(uploadsFolder))
|
||||||
{
|
{
|
||||||
@@ -72,4 +72,11 @@ public class FileUploadController : ControllerBase
|
|||||||
return StatusCode(500, $"Internal server error: {ex.Message}");
|
return StatusCode(500, $"Internal server error: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("[action]")]
|
||||||
|
public async Task<IActionResult> DownloadFile(DownloadFileCriteria criteria)
|
||||||
|
{
|
||||||
|
var rev = await _importPersonRepository.DownloadFile(criteria);
|
||||||
|
return Ok(rev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||||
|
|
||||||
# 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:8.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:8.0 AS build
|
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY ["FamilyTreeAPI/FamilyTreeAPI.csproj", "FamilyTreeAPI/"]
|
COPY ["FamilyTreeAPI/FamilyTreeAPI.csproj", "FamilyTreeAPI/"]
|
||||||
COPY ["CommonAD/CommonAD.csproj", "CommonAD/"]
|
|
||||||
RUN dotnet restore "./FamilyTreeAPI/FamilyTreeAPI.csproj"
|
RUN dotnet restore "./FamilyTreeAPI/FamilyTreeAPI.csproj"
|
||||||
COPY . .
|
COPY . .
|
||||||
WORKDIR "/src/FamilyTreeAPI"
|
WORKDIR "/src/FamilyTreeAPI"
|
||||||
@@ -18,9 +17,9 @@ 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:8.0 AS base
|
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV ASPNETCORE_HTTP_PORTS=80
|
ENV ASPNETCORE_HTTP_PORTS=8080
|
||||||
EXPOSE 80
|
EXPOSE 8080
|
||||||
COPY --from=publish /app/publish .
|
COPY --from=publish /app/publish .
|
||||||
ENTRYPOINT ["dotnet", "FamilyTreeAPI.dll"]
|
ENTRYPOINT ["dotnet", "FamilyTreeAPI.dll"]
|
||||||
@@ -10,6 +10,10 @@ public class FileContent
|
|||||||
public byte[] Content { get; set; }
|
public byte[] Content { get; set; }
|
||||||
public string FileName { get; set; }
|
public string FileName { get; set; }
|
||||||
}
|
}
|
||||||
|
public class DownloadFileCriteria
|
||||||
|
{
|
||||||
|
public string FileName { get; set; }
|
||||||
|
}
|
||||||
public class UploadCriteria
|
public class UploadCriteria
|
||||||
{
|
{
|
||||||
public string FileName { get; set; }
|
public string FileName { get; set; }
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
The family Tree
|
||||||
|
|
||||||
|
Man and Woman
|
||||||
|
|
||||||
|
top level
|
||||||
|
|
||||||
|
1) TAM (M) has partner Jenny (F)
|
||||||
|
|
||||||
|
had child CAO (M)
|
||||||
|
had Child Emmy (F)
|
||||||
|
has Child Loan (F)
|
||||||
|
|
||||||
|
|
||||||
|
2) CAO (M) has partner Lin (F)
|
||||||
|
|
||||||
|
has child Joe (M)
|
||||||
|
has child TOM (M)
|
||||||
|
|
||||||
|
|
||||||
|
3) Joe has partner Sophia (F)
|
||||||
|
|
||||||
|
has child Olivia (F)
|
||||||
|
has child Mai (F)
|
||||||
|
|
||||||
|
|
||||||
|
4) Henry has partner Loan (F)
|
||||||
|
|
||||||
|
has child Enya (F)
|
||||||
|
has child Thanh (M)
|
||||||
|
has child Chuong (M)
|
||||||
|
|
||||||
|
5) Henry has partner Brisa (F)
|
||||||
|
has child Fern (F)
|
||||||
|
has child Tim (M)
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
},
|
},
|
||||||
"dotnetRunMessages": true,
|
"dotnetRunMessages": true,
|
||||||
"applicationUrl": "http://localhost:5015",
|
"applicationUrl": "http://localhost:5016",
|
||||||
"applicationUrl1": "http://192.168.8.188:5015"
|
"applicationUrl1": "http://192.168.8.188:5015"
|
||||||
},
|
},
|
||||||
"IIS Express": {
|
"IIS Express": {
|
||||||
|
|||||||
@@ -37,7 +37,67 @@ public class ImportPersonRepository
|
|||||||
_config = config;
|
_config = config;
|
||||||
_httpContext = httpContext;
|
_httpContext = httpContext;
|
||||||
}
|
}
|
||||||
|
public async Task<string> GetImageAsBase64String(string imagePath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Read the image file into a byte array
|
||||||
|
//byte[] imageBytes = File.ReadAllBytes(imagePath);
|
||||||
|
byte[] imageBytes = await File.ReadAllBytesAsync(imagePath);
|
||||||
|
// Convert the byte array to a Base64 string
|
||||||
|
string base64String = Convert.ToBase64String(imageBytes);
|
||||||
|
|
||||||
|
return base64String;
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Error: The file at '{imagePath}' was not found.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"An error occurred: {ex.Message}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<string>> DownloadFile(DownloadFileCriteria criteria)
|
||||||
|
{
|
||||||
|
int statusCode = -1;
|
||||||
|
string result = "";
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
string imagePath = _config.GetValue<string>("AppSettings:ImageFolder");
|
||||||
|
string imageUrl = System.IO.Path.Combine(imagePath, criteria.FileName);
|
||||||
|
if (System.IO.File.Exists(imageUrl))
|
||||||
|
{
|
||||||
|
result = await this.GetImageAsBase64String(imageUrl);
|
||||||
|
statusCode = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error = "error filename " + criteria.FileName + " can not find";
|
||||||
|
statusCode = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
statusCode = -1;
|
||||||
|
error = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<string>
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statusCode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
public async Task<List<CodeDto<string>>> ImportPerson(MemoryStream fileStream, string sheetName)
|
public async Task<List<CodeDto<string>>> ImportPerson(MemoryStream fileStream, string sheetName)
|
||||||
{
|
{
|
||||||
Dictionary<string, ImportRelation> relationDic = new();
|
Dictionary<string, ImportRelation> relationDic = new();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"Kestrel": {
|
"Kestrel_not_use": {
|
||||||
"Endpoints": {
|
"Endpoints": {
|
||||||
"Http": {
|
"Http": {
|
||||||
"Url": "http://*:5015"
|
"Url": "http://*:5015"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ services:
|
|||||||
PGADMIN_DEFAULT_EMAIL: postgres@domain.com
|
PGADMIN_DEFAULT_EMAIL: postgres@domain.com
|
||||||
PGADMIN_DEFAULT_PASSWORD: Positive~1
|
PGADMIN_DEFAULT_PASSWORD: Positive~1
|
||||||
ports:
|
ports:
|
||||||
- "5050:80"
|
- "5050:5050"
|
||||||
networks:
|
networks:
|
||||||
- dev
|
- dev
|
||||||
familytreeui:
|
familytreeui:
|
||||||
@@ -41,7 +41,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: UI
|
context: UI
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: workui
|
container_name: familytreeui
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/app
|
- ./:/app
|
||||||
networks:
|
networks:
|
||||||
@@ -54,8 +54,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- "Logging:Microsoft.AspNetCore.DataProtection:None"
|
- "Logging:Microsoft.AspNetCore.DataProtection:None"
|
||||||
- "AppSettings:SQLConnectionString=host=postgresdb;database=FamilyTreeDB;username=postgres;password=Positive~1"
|
- "AppSettings:SQLConnectionString=host=postgresdb;database=FamilyTreeDB;username=postgres;password=Positive~1"
|
||||||
volumes:
|
|
||||||
- myapikey:/home/app/.aspnet/DataProtection-Keys
|
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
FROM node:24.0.0 AS build
|
||||||
|
RUN mkdir -p /app
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY ["./*.json", "./"]
|
||||||
|
|
||||||
|
RUN npm install -g @angular/cli
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
# Run command in Virtual directory
|
||||||
|
RUN npm cache clean --force
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
#RUN ng build --configuration=production
|
||||||
|
RUN ng build -c=production
|
||||||
|
|
||||||
|
FROM nginx:latest
|
||||||
|
#### copy nginx conf
|
||||||
|
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
#COPY --from=build app/dist/Familytree/browser /usr/share/nginx/html
|
||||||
|
#### copy artifact build from the 'build environment' old is not in browser folder
|
||||||
|
COPY --from=build /app/dist/Familytree/browser /usr/share/nginx/html
|
||||||
|
|
||||||
|
#CMD ["nginx", "-g", "daemon off;"]
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
#docker build -t my_angular_app:latest .
|
||||||
|
#docker run --name carval -d -p 4200:80 varlidate_ui
|
||||||
|
#npm error code ENOENT
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
sendfile on;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_http_version 1.1;
|
||||||
|
gzip_disable "MSIE [1-6]\.";
|
||||||
|
gzip_min_length 256;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_proxied expired no-cache no-store private auth;
|
||||||
|
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
||||||
|
gzip_comp_level 9;
|
||||||
|
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"baseUrl1": "http://192.168.8.188:5015",
|
"baseUrl1": "http://192.168.8.188:5015",
|
||||||
"baseUrl": "http://localhost:5015",
|
"baseUrl": "http://localhost:5016",
|
||||||
|
"baseUrl_docker": "http://localhost:8080",
|
||||||
"attachment": "http://localhost/document/family"
|
"attachment": "http://localhost/document/family"
|
||||||
}
|
}
|
||||||
@@ -4,12 +4,14 @@ import { StaffComponent, StaffEditComponent } from './staff';
|
|||||||
import { AuthGuard } from './route-guard';
|
import { AuthGuard } from './route-guard';
|
||||||
import { FamilyTree, FamilyList} from './person';
|
import { FamilyTree, FamilyList} from './person';
|
||||||
import { ImportCom } from './import.com/import.com';
|
import { ImportCom } from './import.com/import.com';
|
||||||
|
import { ImageDisplayComponent } from './pickperson/image.display';
|
||||||
export const routes: Routes = [
|
export const routes: Routes = [
|
||||||
{ path: '', redirectTo: 'login', pathMatch: 'full' },
|
{ path: '', redirectTo: 'login', pathMatch: 'full' },
|
||||||
// { path: 'approval', component: ApprovalComponent,canActivate: [AuthGuard], data: { roleAllowed: '1,2,3' }},},
|
// { path: 'approval', component: ApprovalComponent,canActivate: [AuthGuard], data: { roleAllowed: '1,2,3' }},},
|
||||||
{ path: 'login', component: Login},
|
{ path: 'login', component: Login},
|
||||||
{ path: 'staff', component: StaffComponent},
|
{ path: 'staff', component: StaffComponent},
|
||||||
{ path: 'person', component: FamilyList},
|
{ path: 'person', component: FamilyList},
|
||||||
|
{ path: 'imagedisplay/:id', component: ImageDisplayComponent},
|
||||||
{ path: 'import', component: ImportCom},
|
{ path: 'import', component: ImportCom},
|
||||||
{ path: 'familytree', component: FamilyTree},
|
{ path: 'familytree', component: FamilyTree},
|
||||||
{ path: 'staff/:id', component: StaffEditComponent},
|
{ path: 'staff/:id', component: StaffEditComponent},
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<label class="flex mb-2"> Import Excel File</label>
|
<label class="flex mb-2"> Import Excel File</label>
|
||||||
<p-fileupload #fu mode="basic" chooseLabel="Choose"
|
<p-fileupload #fu mode="basic" chooseLabel="Choose"
|
||||||
chooseIcon="pi pi-upload" name="file"
|
chooseIcon="pi pi-upload" name="file"
|
||||||
url="http://localhost:5015/api/FileUpload/UploadFile"
|
url='{{baseUrl}}'
|
||||||
maxFileSize="10000000000" (onUpload)="onUpload($event)" />
|
maxFileSize="10000000000" (onUpload)="onUpload($event)" />
|
||||||
<p-button styleClass="mt-4" label="Upload" (onClick)="fu.upload()" severity="primary" />
|
<p-button styleClass="mt-4" label="Upload" (onClick)="fu.upload()" severity="primary" />
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, inject, OnInit } from '@angular/core';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from 'primeng/button';
|
||||||
import { FileUploadEvent, FileUploadModule } from 'primeng/fileupload';
|
import { FileUploadEvent, FileUploadModule } from 'primeng/fileupload';
|
||||||
import { MessageService } from 'primeng/api';
|
import { MessageService } from 'primeng/api';
|
||||||
import { FileUpload } from 'primeng/fileupload';
|
import { FileUpload } from 'primeng/fileupload';
|
||||||
import { ToastModule } from 'primeng/toast';
|
import { ToastModule } from 'primeng/toast';
|
||||||
|
import { AppSettingService } from '../shares';
|
||||||
/*
|
/*
|
||||||
interface UploadEvent {
|
interface UploadEvent {
|
||||||
originalEvent: Event;
|
originalEvent: Event;
|
||||||
@@ -16,9 +17,17 @@ interface UploadEvent {
|
|||||||
templateUrl: './import.com.html',
|
templateUrl: './import.com.html',
|
||||||
styleUrl: './import.com.css'
|
styleUrl: './import.com.css'
|
||||||
})
|
})
|
||||||
export class ImportCom {
|
export class ImportCom implements OnInit {
|
||||||
uploadedFiles: any[] = [];
|
uploadedFiles: any[] = [];
|
||||||
|
baseUrl = "";
|
||||||
|
private appSetting = inject(AppSettingService);
|
||||||
constructor(private messageService: MessageService) {}
|
constructor(private messageService: MessageService) {}
|
||||||
|
ngOnInit(): void
|
||||||
|
{
|
||||||
|
const cbaseUrl = this.appSetting.appSetting.baseUrl;
|
||||||
|
//http://localhost:5015/api/FileUpload/UploadFile"
|
||||||
|
this.baseUrl = cbaseUrl + "/api/FileUpload/UploadFile";
|
||||||
|
}
|
||||||
onUpload(event:FileUploadEvent) {
|
onUpload(event:FileUploadEvent) {
|
||||||
for(let file of event.files) {
|
for(let file of event.files) {
|
||||||
this.uploadedFiles.push(file);
|
this.uploadedFiles.push(file);
|
||||||
|
|||||||
@@ -12,5 +12,6 @@ export enum ConfigureUrl
|
|||||||
logoutUrl ="api/Users/Logout",
|
logoutUrl ="api/Users/Logout",
|
||||||
adminUserUrl = "api/Staff",
|
adminUserUrl = "api/Staff",
|
||||||
lookupUrl = "api/Lookup",
|
lookupUrl = "api/Lookup",
|
||||||
|
FileUploadUrl = "api/FileUpload",
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,9 +5,7 @@ import { OrganizationChartModule } from 'primeng/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 { PersonService } from './person.service';
|
import { PersonService } from './person.service';
|
||||||
import { AuthenticationService } from '../user-services';
|
|
||||||
import { TableModule } from 'primeng/table';
|
import { TableModule } from 'primeng/table';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
@@ -41,15 +39,13 @@ export class FamilyOrga implements OnInit, OnDestroy{
|
|||||||
familyList:Person[] = [];
|
familyList:Person[] = [];
|
||||||
msg ="[Person organise component]";
|
msg ="[Person organise component]";
|
||||||
private messageService = inject(MessageService);
|
private messageService = inject(MessageService);
|
||||||
|
public ref = inject(DynamicDialogRef);
|
||||||
|
public config = inject(DynamicDialogConfig);
|
||||||
/*
|
/*
|
||||||
private store: Store<appValidationState>
|
private store: Store<appValidationState>
|
||||||
*/
|
*/
|
||||||
constructor(
|
private personService = inject(PersonService);
|
||||||
public dialogService: DialogService,
|
public dialogService = inject(DialogService);
|
||||||
private personService: PersonService,
|
|
||||||
|
|
||||||
public ref: DynamicDialogRef, public config: DynamicDialogConfig,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit(): void
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -52,10 +52,10 @@ export class FamilyList implements OnInit, OnDestroy{
|
|||||||
public dialogService= inject( DialogService);
|
public dialogService= inject( DialogService);
|
||||||
private personService= inject( PersonService);
|
private personService= inject( PersonService);
|
||||||
private confirmationService = inject(ConfirmationService);
|
private confirmationService = inject(ConfirmationService);
|
||||||
private cd = inject(ChangeDetectorRef);
|
private cdr = inject(ChangeDetectorRef);
|
||||||
private authenticationService= inject( AuthenticationService);
|
private authenticationService= inject( AuthenticationService);
|
||||||
private router= inject( Router);
|
private router= inject( Router);
|
||||||
constructor() {}
|
|
||||||
getSearchCiteria(): StaffSearch {
|
getSearchCiteria(): StaffSearch {
|
||||||
let criteria:StaffSearch = {
|
let criteria:StaffSearch = {
|
||||||
email: this.email,
|
email: this.email,
|
||||||
@@ -182,7 +182,7 @@ export class FamilyList implements OnInit, OnDestroy{
|
|||||||
|
|
||||||
console.log("the person from load", this.familyList());
|
console.log("the person from load", this.familyList());
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.cd.detectChanges();
|
this.cdr.detectChanges();
|
||||||
},
|
},
|
||||||
error: e => {
|
error: e => {
|
||||||
const message = e || e.message;
|
const message = e || e.message;
|
||||||
@@ -250,6 +250,7 @@ export class FamilyList implements OnInit, OnDestroy{
|
|||||||
|
|
||||||
const nlist = this.familyList().filter(d => d.id !== id);
|
const nlist = this.familyList().filter(d => d.id !== id);
|
||||||
this.familyList.set(nlist);
|
this.familyList.set(nlist);
|
||||||
|
this.cdr.detectChanges();
|
||||||
},
|
},
|
||||||
error: e => console.error(e)
|
error: e => console.error(e)
|
||||||
});
|
});
|
||||||
@@ -311,19 +312,21 @@ export class FamilyList implements OnInit, OnDestroy{
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateList(item: Person) :void {
|
updateList(item: Person) :void {
|
||||||
const idx = this.familyList().findIndex( x => x.id == item.id);
|
const list = this.familyList();
|
||||||
|
const idx = list.findIndex( x => x.id === item.id);
|
||||||
if (item.fatherId && item.fatherId > 0)
|
if (item.fatherId && item.fatherId > 0)
|
||||||
item.fatherName = this.getName(item.fatherId);
|
item.fatherName = this.getName(item.fatherId);
|
||||||
if (item.motherId && item.motherId > 0)
|
if (item.motherId && item.motherId > 0)
|
||||||
item.motherName = this.getName(item.motherId);
|
item.motherName = this.getName(item.motherId);
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
{
|
{
|
||||||
const olist = [... this.familyList(), item];
|
const olist = [... list, item];
|
||||||
this.familyList.set(olist);
|
this.familyList.set(olist);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const oitem = this.familyList()[idx];
|
|
||||||
|
const oitem = list[idx];
|
||||||
oitem.firstName = item.firstName;
|
oitem.firstName = item.firstName;
|
||||||
oitem.lastName = item.lastName;
|
oitem.lastName = item.lastName;
|
||||||
oitem.address = item.address;
|
oitem.address = item.address;
|
||||||
@@ -335,7 +338,9 @@ export class FamilyList implements OnInit, OnDestroy{
|
|||||||
oitem.motherId = item.motherId;
|
oitem.motherId = item.motherId;
|
||||||
oitem.fatherName = item.fatherName;
|
oitem.fatherName = item.fatherName;
|
||||||
oitem.motherName = item.motherName;
|
oitem.motherName = item.motherName;
|
||||||
|
this.familyList.set(list);
|
||||||
}
|
}
|
||||||
|
this.cdr.markForCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -53,11 +53,15 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="field col-12 md:col-6 sm:col-8">
|
<div class="field col-12 md:col-6 sm:col-8">
|
||||||
|
<div class="shadow-md rounded-xl border-gray-100 border-1 p-4">
|
||||||
@if (adminuserForm.value.image != "" && adminuserForm.value.image != null)
|
@if (adminuserForm.value.image != "" && adminuserForm.value.image != null)
|
||||||
{
|
{
|
||||||
<div class="ml-6 file-upload">
|
<div class="ml-6 file-upload">
|
||||||
<a href="{{hostsite}}/{{adminuserForm.value.image}}" target="_blank" class="text-blue-400">View Attachment
|
<!--a href="{{hostsite}}/{{adminuserForm.value.image}}" target="_blank" class="text-blue-400">View Attachment
|
||||||
</a>
|
</a-->
|
||||||
|
<button pButton type="button" icon="pi pi-image"
|
||||||
|
class ="p-ripple p-button p-button-raised p-button-text p-button-warn p-component"
|
||||||
|
pTooltip="view Image" (click)="doViewImage(adminuserForm.value.image)"></button>
|
||||||
<button pButton type="button" icon="pi pi-times" pTooltip="remove attach file"
|
<button pButton type="button" icon="pi pi-times" pTooltip="remove attach file"
|
||||||
class="p-button-rounded p-button-text text-red-500 p-button-raised ml-2"
|
class="p-button-rounded p-button-text text-red-500 p-button-raised ml-2"
|
||||||
(click)="deleteFile()"></button>
|
(click)="deleteFile()"></button>
|
||||||
@@ -77,9 +81,10 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="mt-2 w-full">
|
<div class="mt-2 w-full">
|
||||||
<p-button class="flex justify-end mr-2" icon="pi pi-user" label="Add Partner"
|
<p-button class="flex justify-end mr-2" icon="pi pi-user" [raised]="true" severity="info" label="Add Partner"
|
||||||
severity="warn" (onClick)="addPartner()"/>
|
(onClick)="addPartner()"/>
|
||||||
<div class="shadow rounded mt-2 mb-2">
|
<div class="shadow rounded mt-2 mb-2">
|
||||||
<p-table [value]="partners()">
|
<p-table [value]="partners()">
|
||||||
<ng-template #header>
|
<ng-template #header>
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ import moment from 'moment';
|
|||||||
import { HttpEvent } from '@angular/common/http';
|
import { HttpEvent } from '@angular/common/http';
|
||||||
import { TableModule } from 'primeng/table';
|
import { TableModule } from 'primeng/table';
|
||||||
import { Pickperson } from '../pickperson/pickperson';
|
import { Pickperson } from '../pickperson/pickperson';
|
||||||
|
import { ImageDisplayComponent } from '../pickperson/image.display';
|
||||||
|
import { TooltipModule } from 'primeng/tooltip';
|
||||||
|
|
||||||
export interface FileUploadEvent {
|
export interface FileUploadEvent {
|
||||||
originalEvent: HttpEvent<any>;
|
originalEvent: HttpEvent<any>;
|
||||||
@@ -30,7 +31,8 @@ export interface FileUploadHandlerEvent {
|
|||||||
@Component({
|
@Component({
|
||||||
templateUrl: 'person.edit.html',
|
templateUrl: 'person.edit.html',
|
||||||
selector: 'person-edit',
|
selector: 'person-edit',
|
||||||
imports:[ButtonModule,TableModule,ReactiveFormsModule,SelectModule,CheckboxModule, InputTextModule,DatePickerModule],
|
imports:[ButtonModule,TableModule,ReactiveFormsModule,TooltipModule,
|
||||||
|
SelectModule,CheckboxModule, InputTextModule,DatePickerModule],
|
||||||
styleUrls: ['person.edit.css'],
|
styleUrls: ['person.edit.css'],
|
||||||
providers: [DialogService]
|
providers: [DialogService]
|
||||||
|
|
||||||
@@ -234,7 +236,6 @@ populateSex(): void {
|
|||||||
status:'M'
|
status:'M'
|
||||||
};
|
};
|
||||||
this.sexList.push(item);
|
this.sexList.push(item);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit():void {
|
ngOnInit():void {
|
||||||
@@ -275,10 +276,33 @@ ngOnInit():void {
|
|||||||
// this for disable submit button
|
// this for disable submit button
|
||||||
get isFieldsChange() {
|
get isFieldsChange() {
|
||||||
const chan = this.isChange || !this.adminuserForm.valid; // this disable so need true valid = true not
|
const chan = this.isChange || !this.adminuserForm.valid; // this disable so need true valid = true not
|
||||||
//console.log(this.msg + 'is fields change', chan);
|
console.log(this.msg + 'is fields change', chan);
|
||||||
return chan;
|
return chan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doViewImage(imageName:string): void {
|
||||||
|
const ref = this.dialogService.open(ImageDisplayComponent, {
|
||||||
|
data: {
|
||||||
|
imageName,
|
||||||
|
},
|
||||||
|
|
||||||
|
header: 'View Image',
|
||||||
|
draggable: true,
|
||||||
|
width: '70%',
|
||||||
|
modal:true,
|
||||||
|
maximizable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
ref.onClose.subscribe((item: Person) => {
|
||||||
|
if (item) {
|
||||||
|
//console.log("after close ward edit", item);
|
||||||
|
this.messageService.add({severity:'success', summary: 'Select', detail: item.firstName!});
|
||||||
|
//update the current list
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
assignValue(item:Person): void {
|
assignValue(item:Person): void {
|
||||||
this._id = item.id;
|
this._id = item.id;
|
||||||
this.fileName = item.image!;
|
this.fileName = item.image!;
|
||||||
@@ -537,7 +561,7 @@ showPickPerson(title:string, callback:(id: Person) => void) :void {
|
|||||||
},
|
},
|
||||||
header: title,
|
header: title,
|
||||||
width: '80%',
|
width: '80%',
|
||||||
|
draggable: true,
|
||||||
maximizable: true
|
maximizable: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,13 @@ 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>> {
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.FileUploadUrl + "/DownloadFile";
|
||||||
|
const data = {
|
||||||
|
fileName: imageName
|
||||||
|
};
|
||||||
|
return this.http.post<ResultModel<string>>(baseUrl, data);
|
||||||
|
}
|
||||||
deleteUploadFile(data: any): Observable<ResultModel<number>> {
|
deleteUploadFile(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";
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<img [src]="imageDataUrl" alt="Person Image" width="400" height="300"/>
|
||||||
|
<div class="flex justify-end">
|
||||||
|
|
||||||
|
<button pButton pRipple class="p-button-sm mr-2 p-button-secondary" type="button" icon="pi pi-sign-in" label="Close"
|
||||||
|
(click)="close()"></button>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import { Component, inject, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
|
||||||
|
import { AppSettingService } from '../shares';
|
||||||
|
import { PersonService } from '../person';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-image-display',
|
||||||
|
imports:[CommonModule, ButtonModule],
|
||||||
|
templateUrl: './image.display.html',
|
||||||
|
styleUrls: ['./image.display.css']
|
||||||
|
})
|
||||||
|
export class ImageDisplayComponent implements OnInit, OnDestroy {
|
||||||
|
//base64ImageString: string = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='; // Example Base64 (a tiny red dot PNG)
|
||||||
|
//imageDataUrl: SafeResourceUrl ={};
|
||||||
|
imageDataUrl = "";
|
||||||
|
private personService = inject(PersonService);
|
||||||
|
private sanitizer = inject(DomSanitizer);
|
||||||
|
//private route = inject(ActivatedRoute);
|
||||||
|
public ref = inject(DynamicDialogRef);
|
||||||
|
public config = inject(DynamicDialogConfig);
|
||||||
|
private subscription:Subscription = new Subscription();
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
|
||||||
|
const imageName = this.config.data.imageName;
|
||||||
|
this.loadImage(imageName);
|
||||||
|
|
||||||
|
}
|
||||||
|
loadImage(fileName: string| null): void {
|
||||||
|
const download = this.personService.downloadFile(fileName!);
|
||||||
|
this.subscription.add(download.subscribe({
|
||||||
|
next: x => {
|
||||||
|
if (x.statusCode == 1)
|
||||||
|
{
|
||||||
|
this.display(x.data);
|
||||||
|
console.log("this is show image" , this.imageDataUrl, x);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log("error in download in api ", x.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: e => console.error("error in download image", e)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
display(baseImage: string): void
|
||||||
|
{
|
||||||
|
const changeUrl = (this.sanitizer.bypassSecurityTrustResourceUrl(baseImage) as any).changingThisBreaksApplicationSecurity;
|
||||||
|
console.log('this is bypassSecurityTrustResourceUrl', changeUrl);
|
||||||
|
const fullDataUri = `data:image/png;base64,${changeUrl}`;
|
||||||
|
this.imageDataUrl = fullDataUri
|
||||||
|
}
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
close() :void {
|
||||||
|
this.ref.close(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user