Commit 66a890c0 by pantakan konthang

แก้ปุ่ม PDF

parent 530c28df
...@@ -617,7 +617,7 @@ ...@@ -617,7 +617,7 @@
<app-pms-idp [currentTap]="currentTap" [canSave]="canSave" [appraisalIdp]="compentency.data.idp" <app-pms-idp [currentTap]="currentTap" [canSave]="canSave" [appraisalIdp]="compentency.data.idp"
[evaluaterId]="evaluaterId" [evaluateeId]="evaluateeId" [evaluaterId]="evaluaterId" [evaluateeId]="evaluateeId"
[canEdit]="evaluationForm=='sup'?canEdit:false" [currentStep]="compentency.data.currentStep" [canEdit]="evaluationForm=='sup'?canEdit:false" [currentStep]="compentency.data.currentStep"
[dateIso]="dateIso" (idpForm)="compentency.data.idp=$event" [complete]="complete" [pdfPrint]="pdfPrint" (pdfPrinted)="onPdfPrinted()"></app-pms-idp> [dateIso]="dateIso" (idpForm)="compentency.data.idp=$event" [complete]="complete"></app-pms-idp>
</div> </div>
<ng-container *ngIf="compentency.data&&canSave"> <ng-container *ngIf="compentency.data&&canSave">
<div class="box-footer text-end space-x-3 rtl:space-x-reverse" <div class="box-footer text-end space-x-3 rtl:space-x-reverse"
...@@ -626,11 +626,11 @@ ...@@ -626,11 +626,11 @@
<textarea type="text" class="ti-form-input" rows="2" placeholder="ใส่ Comment ที่นี่" <textarea type="text" class="ti-form-input" rows="2" placeholder="ใส่ Comment ที่นี่"
[(ngModel)]="comment"></textarea> [(ngModel)]="comment"></textarea>
</div> </div>
<button (click)="toggleStatusPdfPrint()" class="ti-btn m-0 ti-btn-soft-warning" <!-- <button (click)="toggleStatusPdfPrint()" class="ti-btn m-0 ti-btn-soft-warning"
*ngIf="currentTap == 'แผนพัฒนาบุคลากร'"> *ngIf="currentTap == 'แผนพัฒนาบุคลากร'">
<i class="ri-draft-fill"></i> <i class="ri-draft-fill"></i>
PDF PDF
</button> </button> -->
<button (click)="save('approve')" class="ti-btn m-0 ti-btn-soft-secondary" <button (click)="save('approve')" class="ti-btn m-0 ti-btn-soft-secondary"
[disabled]="compentencyFormRemain||kpiFormRemain" [disabled]="compentencyFormRemain||kpiFormRemain"
[class.ti-btn-disabled]="compentencyFormRemain||kpiFormRemain"> [class.ti-btn-disabled]="compentencyFormRemain||kpiFormRemain">
......
...@@ -74,7 +74,6 @@ export class PmsFormEmployeeComponent { ...@@ -74,7 +74,6 @@ export class PmsFormEmployeeComponent {
complete = false complete = false
@ViewChild('scrollContainer') scrollContainer!: ElementRef; @ViewChild('scrollContainer') scrollContainer!: ElementRef;
pdfPrint = false;
constructor( constructor(
private router: Router, private router: Router,
...@@ -760,13 +759,4 @@ export class PmsFormEmployeeComponent { ...@@ -760,13 +759,4 @@ export class PmsFormEmployeeComponent {
imgElement.src = './assets/img/users/defaultperson.jpg'; imgElement.src = './assets/img/users/defaultperson.jpg';
} }
toggleStatusPdfPrint() {
this.pdfPrint = !this.pdfPrint; // สลับ true/false เพื่อให้ Child จับการเปลี่ยน
}
onPdfPrinted() {
// เมื่อ Child แจ้งว่าพิมพ์เสร็จ ให้รีเซ็ตกลับเป็น false
this.pdfPrint = false;
}
} }
...@@ -2,10 +2,26 @@ ...@@ -2,10 +2,26 @@
<ng-template #idpEvaluation> <ng-template #idpEvaluation>
<ng-container *ngIf="appraisalIdp"> <ng-container *ngIf="appraisalIdp">
<div style="overflow-y: auto; padding-top: 1rem" #pdfArea class="pdf-container"> <div style="overflow-y: auto; padding-top: 1rem" #pdfArea class="pdf-container">
<div class="pb-2">
<!-- <ng-container *ngIf="pdfPrintCheck === 1">
<div *ngFor="let item of [1,2,3]" class="ti-spinner w-8 h-8 text-secondary mx-1"
role="status" aria-label="loading">
<span class="sr-only">Loading...</span>
</div>
</ng-container> -->
<ng-container>
<div class="pb-2 flex justify-between items-center">
<div class="font-size-18px font-weight-700 text-gray-500"> <div class="font-size-18px font-weight-700 text-gray-500">
ส่วนที่ 1: ข้อมูลทั่วไป ส่วนที่ 1: ข้อมูลทั่วไป
</div> </div>
<!-- <button class="ti-btn m-0 ti-btn-soft-warning" *ngIf="pdfPrintCheck == 0" (click)="exportPdf()" >
<i class="ri-draft-fill"></i>
PDF
</button> -->
<button class="ti-btn m-0 ti-btn-soft-warning" data-html2canvas-ignore="true" data-hide-in-pdf (click)="exportPdf()">
<i class="ri-draft-fill"></i> PDF
</button>
</div> </div>
<div class="pt-2 pb-2rem"> <div class="pt-2 pb-2rem">
<div class="flex flex-row gap-2 "> <div class="flex flex-row gap-2 ">
...@@ -344,7 +360,7 @@ ...@@ -344,7 +360,7 @@
</ng-container> </ng-container>
</ng-container> </ng-container>
<ng-container *ngIf="pdfPrintCheck == 1"> <ng-container *ngIf="pdfPrintCheck != 0">
{{convertDateFormat(appraisalIdp.masfromEvaluationRound.apsPeriodStart)}} {{convertDateFormat(appraisalIdp.masfromEvaluationRound.apsPeriodStart)}}
<ng-container <ng-container
*ngIf="appraisalIdp.masfromEvaluationRound.apsPeriodStart &&appraisalIdp.masfromEvaluationRound.apsPeriodEnd"> *ngIf="appraisalIdp.masfromEvaluationRound.apsPeriodStart &&appraisalIdp.masfromEvaluationRound.apsPeriodEnd">
...@@ -361,6 +377,9 @@ ...@@ -361,6 +377,9 @@
</table> </table>
</div> </div>
</div> </div>
</ng-container>
</div> </div>
</ng-container> </ng-container>
</ng-template> </ng-template>
......
...@@ -37,7 +37,7 @@ export class PmsIdpComponent { ...@@ -37,7 +37,7 @@ export class PmsIdpComponent {
@Output() idpForm: EventEmitter<any> = new EventEmitter<any>(); @Output() idpForm: EventEmitter<any> = new EventEmitter<any>();
@Input() pdfPrint = false; @Input() pdfPrint = false;
@Output() pdfPrinted = new EventEmitter<void>(); @Output() pdfPrinted = new EventEmitter<void>();
pdfPrintCheck = 0 pdfPrintCheck: 0 | 1 = 0
@ViewChild('pdfArea') pdfArea!: ElementRef<HTMLElement>; @ViewChild('pdfArea') pdfArea!: ElementRef<HTMLElement>;
competencycourse: { loading: boolean, data: CompetencycourseMiniModel[] } = { loading: false, data: [] } competencycourse: { loading: boolean, data: CompetencycourseMiniModel[] } = { loading: false, data: [] }
...@@ -48,6 +48,7 @@ export class PmsIdpComponent { ...@@ -48,6 +48,7 @@ export class PmsIdpComponent {
pageSize: 10 pageSize: 10
} }
competencycourseIndex = -1 competencycourseIndex = -1
pdfLoading = true
@ViewChild("competencycourseModal") competencycourseModal: any; @ViewChild("competencycourseModal") competencycourseModal: any;
dialogRefCompetencycourseModal: any dialogRefCompetencycourseModal: any
constructor(private evaluationIdpService: EvaluationIdpService, constructor(private evaluationIdpService: EvaluationIdpService,
...@@ -62,17 +63,6 @@ export class PmsIdpComponent { ...@@ -62,17 +63,6 @@ export class PmsIdpComponent {
this.getCompetencycourseMiniList() this.getCompetencycourseMiniList()
} }
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
if (changes['pdfPrint']) {
const { previousValue, currentValue } = changes['pdfPrint'];
console.log('pdfPrint changed:', previousValue, '→', currentValue);
// สั่งพิมพ์เฉพาะตอนเป็น true
if (currentValue === true) {
this.pdfPrintCheck = 1
this.exportPdf();
this.pdfPrinted.emit(); // แจ้ง Parent ให้รีเซ็ต flag
}
}
if (changes['currentTap']?.currentValue || changes['appraisalIdp']?.currentValue) { if (changes['currentTap']?.currentValue || changes['appraisalIdp']?.currentValue) {
this.getFormIdp() this.getFormIdp()
} }
...@@ -190,10 +180,10 @@ export class PmsIdpComponent { ...@@ -190,10 +180,10 @@ export class PmsIdpComponent {
print() { print() {
window.print(); window.print();
} }
/** ล็อคความกว้างเทียบ A4 (≈794px @96dpi) ให้ layout เสถียรตอนแคปเจอร์ */ /** ล็อคความกว้างเทียบ A4 (≈794px @96dpi) ให้ layout เสถียรตอนแคปเจอร์ */
private freezeWidthForA4(el: HTMLElement) { private freezeWidthForA4(el: HTMLElement) {
const prev = { const prev = {
width: el.style.width, width: el.style.width,
maxWidth: el.style.maxWidth, maxWidth: el.style.maxWidth,
...@@ -211,10 +201,10 @@ private freezeWidthForA4(el: HTMLElement) { ...@@ -211,10 +201,10 @@ private freezeWidthForA4(el: HTMLElement) {
el.style.transform = prev.transform; el.style.transform = prev.transform;
el.style.transformOrigin = prev.transformOrigin; el.style.transformOrigin = prev.transformOrigin;
}; };
} }
/** ขยายเป็นความกว้างจริง (scrollWidth) แล้วสเกลลงให้พอดี A4 */ /** ขยายเป็นความกว้างจริง (scrollWidth) แล้วสเกลลงให้พอดี A4 */
private expandToFullWidthThenScale(el: HTMLElement) { private expandToFullWidthThenScale(el: HTMLElement) {
const A4_PX = 794; // ≈ 210mm @ 96dpi const A4_PX = 794; // ≈ 210mm @ 96dpi
const full = el.scrollWidth; // ความกว้างจริงทั้งหมด (รวมพื้นที่ต้องเลื่อนขวา) const full = el.scrollWidth; // ความกว้างจริงทั้งหมด (รวมพื้นที่ต้องเลื่อนขวา)
const scale = Math.min(1, A4_PX / full); // สเกลลงให้พอดี A4 (ถ้ากว้างกว่า) const scale = Math.min(1, A4_PX / full); // สเกลลงให้พอดี A4 (ถ้ากว้างกว่า)
...@@ -243,11 +233,11 @@ private expandToFullWidthThenScale(el: HTMLElement) { ...@@ -243,11 +233,11 @@ private expandToFullWidthThenScale(el: HTMLElement) {
el.style.transform = prev.transform; el.style.transform = prev.transform;
el.style.transformOrigin = prev.transformOrigin; el.style.transformOrigin = prev.transformOrigin;
}; };
} }
/** ทำให้ทุกกล่องใน subtree ไม่ตัดขอบขวา: overflowX => visible, ยกเลิก position:sticky ชั่วคราว */ /** ทำให้ทุกกล่องใน subtree ไม่ตัดขอบขวา: overflowX => visible, ยกเลิก position:sticky ชั่วคราว */
private unclipOverflows(el: HTMLElement) { private unclipOverflows(el: HTMLElement) {
const patched: Array<{node: HTMLElement, prev: Partial<CSSStyleDeclaration>}> = []; const patched: Array<{ node: HTMLElement, prev: Partial<CSSStyleDeclaration> }> = [];
const walker = document.createTreeWalker(el, NodeFilter.SHOW_ELEMENT); const walker = document.createTreeWalker(el, NodeFilter.SHOW_ELEMENT);
const patchNode = (node: HTMLElement) => { const patchNode = (node: HTMLElement) => {
...@@ -289,12 +279,13 @@ private unclipOverflows(el: HTMLElement) { ...@@ -289,12 +279,13 @@ private unclipOverflows(el: HTMLElement) {
(node.style as any).clipPath = prev.clipPath || ''; (node.style as any).clipPath = prev.clipPath || '';
} }
}; };
} }
// @ViewChild('pdfArea') pdfArea!: ElementRef<HTMLElement>; // @ViewChild('pdfArea') pdfArea!: ElementRef<HTMLElement>;
async exportPdf() { async exportPdf() {
this.pdfPrintCheck = 1
const el = this.pdfArea?.nativeElement; const el = this.pdfArea?.nativeElement;
if (!el) return; if (!el) return;
...@@ -315,8 +306,8 @@ async exportPdf() { ...@@ -315,8 +306,8 @@ async exportPdf() {
const epsilon = 2; // กันเผื่อ const epsilon = 2; // กันเผื่อ
const opt = { const opt = {
margin: [10,10,10,10], margin: [10, 10, 10, 10],
filename: `pms-${this.evaluateeId || 'employee'}-${new Date().toISOString().slice(0,10)}.pdf`, filename: `pms-${this.evaluateeId || 'employee'}-${new Date().toISOString().slice(0, 10)}.pdf`,
image: { type: 'jpeg', quality: 0.96 }, image: { type: 'jpeg', quality: 0.96 },
html2canvas: { html2canvas: {
scale: 2, scale: 2,
...@@ -334,7 +325,10 @@ async exportPdf() { ...@@ -334,7 +325,10 @@ async exportPdf() {
// foreignObjectRendering: true, // ลองเปิดถ้า layout ยังเพี้ยน (มีข้อจำกัดกับบางเคส) // foreignObjectRendering: true, // ลองเปิดถ้า layout ยังเพี้ยน (มีข้อจำกัดกับบางเคส)
}, },
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
pagebreak: { mode: ['css','legacy'], avoid: ['.no-break','table','img'] } pagebreak: { mode: ['css', 'legacy'], avoid: ['.no-break', 'table', 'img'] },
onclone: (doc:any) => {
doc.querySelectorAll('[data-hide-in-pdf]').forEach((el:any) => el.remove());
}
}; };
try { try {
...@@ -345,7 +339,7 @@ async exportPdf() { ...@@ -345,7 +339,7 @@ async exportPdf() {
document.body.style.overflow = prevBodyOverflow; document.body.style.overflow = prevBodyOverflow;
} }
this.pdfPrintCheck = 0 this.pdfPrintCheck = 0
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment