Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
myjob-manage
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
angular
myjob-manage
Commits
a2ae82b1
Commit
a2ae82b1
authored
Jul 02, 2025
by
DESKTOP-E3GSHH7\myhr
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
การจัดการบทความ
parent
ec2177a8
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
929 additions
and
1 deletions
+929
-1
article-manage.component.css
...pp/DPU/common/article-manage/article-manage.component.css
+28
-0
article-manage.component.html
...p/DPU/common/article-manage/article-manage.component.html
+360
-0
article-manage.component.ts
...app/DPU/common/article-manage/article-manage.component.ts
+410
-0
common.module.ts
src/app/DPU/common/common.module.ts
+8
-1
article.model.ts
src/app/DPU/models/article.model.ts
+60
-0
article.service.ts
src/app/DPU/services/article.service.ts
+56
-0
nav.service.ts
src/app/shared/services/nav.service.ts
+7
-0
No files found.
src/app/DPU/common/article-manage/article-manage.component.css
0 → 100644
View file @
a2ae82b1
:host
{
display
:
block
;
}
.small-html
{
font-size
:
0.85rem
;
/* ลดขนาดฟอนต์ */
line-height
:
1.2
;
/* ลดระยะบรรทัด */
max-height
:
150px
;
/* จำกัดความสูง */
overflow-y
:
auto
;
/* ถ้าเนื้อหายาวเกิน ให้เลื่อนดูได้ */
display
:
block
;
}
.border-radius-1
{
border-radius
:
0.50rem
;
}
.font-14
{
font-size
:
14px
;
}
.font-16
{
font-size
:
16px
;
}
.font-24
{
font-size
:
24px
;
}
.font-36
{
font-size
:
36px
;
}
\ No newline at end of file
src/app/DPU/common/article-manage/article-manage.component.html
0 → 100644
View file @
a2ae82b1
<app-page-header
[
title
]="'จัดการบทความ'"
[
activeTitle
]="'ผู้ดูแลระบบ'"
[
title1
]="'จัดการบทความ'"
></app-page-header>
<div
class=
"grid grid-cols-12 gap-6"
>
<div
class=
"xl:col-span-12 col-span-12"
>
<div
class=
"box"
>
<div
class=
"box-header justify-between"
>
<div
class=
"box-title"
>
{{ 'All List' | translate}}
<span
class=
"badge bg-light text-default rounded-full ms-1 text-[0.75rem] align-middle"
>
{{itemsList.length}}
</span>
</div>
<div
class=
"flex flex-wrap gap-2"
>
<a
href=
"javascript:void(0);"
class=
"hs-dropdown-toggle ti-btn ti-btn-primary-full me-2"
(
click
)="
new
()"
(
click
)="
openDialog
()"
data-hs-overlay=
"#modal-detail"
><i
class=
"ri-add-line font-semibold align-middle"
></i>
{{ 'Create' |
translate}}
</a>
<a
href=
"javascript:void(0);"
class=
"hs-dropdown-toggle ti-btn ti-btn-success-full me-2"
*
ngIf=
"someSelected"
(
click
)="
adjustSelect
(
1
)"
><i
class=
"ri-user-follow-line font-semibold align-middle"
></i>
{{ 'Active' |
translate}}
</a>
<a
href=
"javascript:void(0);"
class=
"hs-dropdown-toggle ti-btn ti-btn-secondary-full me-2"
*
ngIf=
"someSelected"
(
click
)="
adjustSelect
(
0
)"
><i
class=
"ri-user-unfollow-line font-semibold align-middle"
></i>
{{ 'Unactive' |
translate}}
</a>
<a
href=
"javascript:void(0);"
class=
"hs-dropdown-toggle ti-btn ti-btn-danger-full me-2"
*
ngIf=
"someSelected"
(
click
)="
deleteSelect
()"
><i
class=
"ri-delete-bin-line font-semibold align-middle"
></i>
{{ 'Delete' |
translate}}
</a>
<div>
<input
class=
"form-control form-control"
type=
"text"
placeholder=
"ค้นหาบริษัท"
aria-label=
".form-control-sm example"
[(
ngModel
)]='
searchTerm
'
>
</div>
</div>
</div>
<div
class=
"box-body"
>
<div
class=
"table-responsive"
>
<table
class=
"table whitespace-nowrap min-w-full ti-custom-table-hover"
>
<thead>
<tr
class=
"border-b border-defaultborder"
>
<th
scope=
"col"
class=
"!text-start"
>
<input
class=
"form-check-input check-all"
type=
"checkbox"
id=
"all-products"
(
change
)="
toggleAll
($
event
)"
[
checked
]="
allSelected
"
aria-label=
"..."
>
</th>
<th
scope=
"col"
class=
"text-start"
>
รูปภาพ
</th>
<th
scope=
"col"
class=
"text-start"
>
หัวข้อบทความ
</th>
<th
scope=
"col"
class=
"text-start"
>
ผู้เขียนบทความ
</th>
<!-- <th scope="col" class="text-start">{{"Status" | translate}}</th> -->
<th
scope=
"col"
class=
"text-start"
>
วันที่สร้าง
</th>
<th
scope=
"col"
class=
"text-start"
>
วันที่เเก้ไขล่าสุด
</th>
<!-- <th scope="col" class="text-start">{{"Update Date" | translate}}</th> -->
<th
scope=
"col"
class=
"text-start"
>
การจัดการ
</th>
</tr>
</thead>
<tbody>
@if (filterList.length > 0) {
@for (item of filterList; track item.articleId) {
<tr
class=
"border border-defaultborder dark:border-defaultborder/10"
>
<td
class=
"product-checkbox"
>
<input
class=
"form-check-input"
type=
"checkbox"
[
checked
]="
selectedItems
.
get
(
item
.
articleId
)
||
false
"
(
change
)="
onCheckboxChange
(
item
.
articleId
)"
aria-label=
"..."
>
</td>
<td>
<div
class=
"flex items-center"
>
<span
class=
"p-3 me-1"
>
<img
[
src
]="
item
.
getPicture
()"
alt=
""
id=
"profile-img"
class=
"border-radius-1"
>
</span>
</div>
</td>
<td>
<div>
<span
class=
"block mb-1"
>
{{item.title}}
</span>
</div>
</td>
<td>
<div>
<span
class=
"block mb-1"
>
{{item.author}}
</span>
</div>
</td>
<!-- <td>
<span class="badge bg-{{ item.status == 1 ? 'primary' : 'danger'}} text-white">
{{item.getStatus()}}
</span>
</td> -->
<td>
<span
class=
"badge bg-info/10 text-primary"
>
<i
class=
"bi bi-clock me-1"
></i>
{{item.createdDate | date : 'medium'}}
</span>
</td>
<td>
<span
class=
"badge bg-info/10 text-primary"
>
<i
class=
"bi bi-clock me-1"
></i>
{{item.lastModifiedDate | date : 'medium'}}
</span>
</td>
<td>
<div
class=
"flex flex-row items-center !gap-2 "
>
<a
aria-label=
"anchor"
(
click
)="
viewArticleDetail
(
item
.
articleId
)"
class=
"ti-btn ti-btn-wave !gap-0 !m-0 bg-info/10 text-info hover:bg-info hover:text-white hover:border-info"
>
<i
class=
"ri-search-line"
></i>
</a>
<a
aria-label=
"anchor"
(
click
)="
view
(
item
)"
(
click
)="
openDialog
()"
class=
"ti-btn ti-btn-wave !gap-0 !m-0 bg-info/10 text-info hover:bg-info hover:text-white hover:border-info"
>
<i
class=
"ri-pencil-line"
></i>
</a>
<a
aria-label=
"anchor"
href=
"javascript:void(0);"
(
click
)="
delete
(
item
)"
class=
"ti-btn ti-btn-wave product-btn !gap-0 !m-0 bg-danger/10 text-danger hover:bg-danger hover:text-white hover:border-danger"
>
<i
class=
"ri-delete-bin-line"
></i>
</a>
</div>
</td>
</tr>
}
} @else {
<tr>
<td
[
attr
.
colspan
]="
6
"
class=
"text-center py-4"
>
<ng-container
*
ngIf=
"itemsList.length === 0 && !searchTerm"
>
<p>
กำลังโหลดข้อมูล หรือไม่มีข้อมูลเลย...
</p>
</ng-container>
<ng-container
*
ngIf=
"itemsList.length > 0 && filterList.length === 0 && searchTerm"
>
<p>
ไม่พบข้อมูลที่ค้นหา...
</p>
</ng-container>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<div
class=
"box-footer"
>
<div
class=
"flex items-center flex-wrap overflow-auto"
*
ngIf=
"filterList.length > 0"
>
<div
class=
"mb-2 sm:mb-0"
>
<div>
{{'Showing' | translate}} {{filterList.length}} {{'entries'
| translate}}
<i
class=
"bi bi-arrow-right ms-2 font-semibold"
></i>
</div>
</div>
<div
class=
"ms-auto"
>
<nav
aria-label=
"Page navigation"
>
<ul
class=
"ti-pagination mb-0"
>
<li
*
ngIf=
"pageIndex>0"
class=
"page-item {{pageIndex==0 ? 'disabled' : ''}}"
><a
class=
"page-link px-3 py-[0.375rem]"
(
click
)="
pageIndex =
pageIndex-1;updatePagedItems()"
>
{{'Previous' | translate}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"pageIndex-1>0"
(
click
)="
pageIndex =
pageIndex-2;updatePagedItems()"
>
{{pageIndex-1}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"pageIndex>0 && ((pageIndex-1)*10 < (searchTerm == '' ? itemsList.length : filterList.length))"
(
click
)="
pageIndex =
pageIndex-1;updatePagedItems()"
>
{{pageIndex}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link active px-3 py-[0.375rem]"
href=
"javascript:void(0);"
>
{{pageIndex +1}}
</a>
</li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"(pageIndex+1)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
(
click
)="
pageIndex =
pageIndex+1;updatePagedItems()"
>
{{pageIndex +2}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"(pageIndex+2)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
(
click
)="
pageIndex =
pageIndex+2;updatePagedItems()"
>
{{pageIndex +3}}
</a></li>
<li
*
ngIf=
"(pageIndex+1)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
(
click
)="
pageIndex =
pageIndex+1;updatePagedItems()"
>
{{'Next' |
translate}}
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>
<ng-template
#
articleModel
let-modal
>
<h3
mat-dialog-title
>
<h3
class=
"modal-title text-[1rem] font-semibold text-defaulttextcolor"
id=
"mail-ComposeLabel"
>
{{ 'Create' |
translate }}{{ 'บทความ' | translate }}
</h3>
</h3>
<div
class=
"w-full flex justify-end"
>
<div
class=
"absolute flex"
>
<div
class=
"px-1"
>
</div>
</div>
</div>
<mat-dialog-content>
<div
class=
"box p-9 top-4"
>
<div
class=
"grid grid-cols-12 gap-4"
>
<div
class=
"xl:col-span-12 col-span-12 justify-items-center"
>
<div
class=
"mb-0 text-center"
>
<span
class=
""
>
<img
[
src
]="
selectModel
.
getPicture
()"
alt=
""
id=
"profile-img"
class=
"border-radius-1"
style=
"width: 300px; height: 200px;"
>
<span
class=
"badge rounded-full bg-primary avatar-badge"
>
<input
ng2FileSelect
[
uploader
]="
uploaderProfile
"
type=
"file"
name=
"photo"
class=
"absolute w-full h-full opacity-[0]"
id=
"profile-change"
>
<i
class=
"fe fe-camera text-[.625rem]"
></i>
</span>
</span>
</div>
</div>
<div
class=
"xl:col-span-6 col-span-12"
>
<label
for=
"articleId"
class=
"text-primary mt-4 font-bold font-14"
>
{{'รหัสบทความ' | translate}}
</label>
<input
type=
"text"
class=
"form-control"
id=
"articleId"
placeholder=
""
[(
ngModel
)]="
selectModel
.
articleId
"
[
readonly
]="
action =
==
'
edit
'"
[
ngClass
]="{
'!
bg-input-readonly
'
:
action =
==
'
edit
'
}"
>
<div
class=
"text-danger"
*
ngIf=
"!selectModel.articleId && action === 'add'"
>
{{'Please fill in information' | translate}}
</div>
</div>
<div
class=
"xl:col-span-6 col-span-12"
>
<label
for=
"title"
class=
"text-primary mt-4 font-bold font-14"
>
{{'ชื่อหัวข้อบทความ' | translate}}
</label>
<input
type=
"text"
class=
"form-control"
id=
"title"
placeholder=
""
[(
ngModel
)]="
selectModel
.
title
"
>
<div
class=
"text-danger"
*
ngIf=
"!selectModel.title"
>
{{'Please fill in information' | translate}}
</div>
</div>
<div
class=
"xl:col-span-12 col-span-12"
>
<label
for=
"author"
class=
"form-label"
>
{{'ผู้เขียนบทความ' | translate}}
</label>
<input
type=
"text"
class=
"form-control"
id=
"author"
placeholder=
""
[(
ngModel
)]="
selectModel
.
author
"
>
<div
class=
"text-danger"
*
ngIf=
"!selectModel.author"
>
{{'Please fill in information' | translate}}
</div>
</div>
<div
class=
"xl:col-span-6 col-span-12"
>
<label
for=
"createdDate"
class=
"form-label"
>
{{'วันที่สร้าง' | translate}}
</label>
<input
type=
"datetime-local"
class=
"form-control"
id=
"createdDate"
placeholder=
""
[(
ngModel
)]="
selectModel
.
createdDate
"
>
<div
class=
"text-danger"
*
ngIf=
"!selectModel.createdDate"
>
{{'Please fill in information' | translate}}
</div>
</div>
<div
class=
"xl:col-span-6 col-span-12"
>
<label
for=
"lastModifiedDate"
class=
"form-label"
>
{{'วันที่เเก้ไขล่าสุด' | translate}}
</label>
<input
type=
"datetime-local"
class=
"form-control"
id=
"lastModifiedDate"
placeholder=
""
[(
ngModel
)]="
selectModel
.
lastModifiedDate
"
>
<div
class=
"text-danger"
*
ngIf=
"!selectModel.lastModifiedDate"
>
{{'Please fill in information' | translate}}
</div>
</div>
<div
class=
"xl:col-span-6 col-span-12"
>
<label
for=
"Detail_d"
>
{{"เรื่องย่อ" | translate}}:
<span
class=
"text-danger"
>
*
</span></label>
<quill-editor
[(
ngModel
)]="!
selectModel
.
excerpt
"
[
modules
]="
quillConfig
"
[
styles
]="{
height:
'
200px
'}"
theme=
"snow"
(
onEditorCreated
)="
onEditorCreated
($
event
)"
(
onContentChanged
)="
onContentChanged
($
event
)"
#
excerpt=
"ngModel"
>
</quill-editor>
</div>
</div>
</div>
</mat-dialog-content>
<mat-dialog-actions>
<button
type=
"button"
class=
"hs-dropdown-toggle ti-btn ti-btn-light align-middle"
data-hs-overlay=
"#modal-detail"
>
{{'Cancel' | translate}}
</button>
<button
type=
"button"
(
click
)="
save
()"
class=
"ti-btn bg-primary text-white !font-medium"
>
{{'Save' |
translate}}
</button>
</mat-dialog-actions>
</ng-template>
<!-- <div id="modal-detail" class="hs-overlay hidden ti-modal [--overlay-backdrop:static]">
<div class="hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out">
<div class="ti-modal-content">
<div class="ti-modal-header">
<h6 class="modal-title text-[1rem] font-semibold text-defaulttextcolor" id="mail-ComposeLabel">{{ 'Create' |
translate }} {{ 'บทความ' | translate }}
</h6>
<button type="button" class="hs-dropdown-toggle !text-[1rem] !font-semibold !text-defaulttextcolor"
data-hs-overlay="#modal-detail" #closeModal>
<span class="sr-only">{{'Close' | translate}}</span>
<i class="ri-close-line"></i>
</button>
</div>
<div class="ti-modal-body px-4">
<div class="grid grid-cols-12 gap-4">
<div class="xl:col-span-12 col-span-12">
<div class="mb-0 text-center">
<span class="avatar avatar-xxl avatar-rounded">
<img [src]="selectModel.getPicture()" alt="" id="profile-img">
<span class="badge rounded-full bg-primary avatar-badge">
<input ng2FileSelect [uploader]="uploaderProfile" type="file" name="photo"
class="absolute w-full h-full opacity-[0]" id="profile-change">
<i class="fe fe-camera text-[.625rem]"></i>
</span>
</span>
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label for="articleId" class="form-label">{{'รหัสบทความ' | translate}}</label>
<input type="text" class="form-control" id="articleId" placeholder="" [(ngModel)]="selectModel.articleId"
[readonly]="action === 'edit'" [ngClass]="{ '!bg-input-readonly': action === 'edit' }">
<div class="text-danger" *ngIf="!selectModel.articleId && action === 'add'">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label for="title" class="form-label">{{'ชื่อหัวข้อบทความ' | translate}}</label>
<input type="text" class="form-control" id="title" placeholder="" [(ngModel)]="selectModel.title">
<div class="text-danger" *ngIf="!selectModel.title">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label for="author" class="form-label">{{'ผู้เขียนบทความ' | translate}}</label>
<input type="text" class="form-control" id="author" placeholder="" [(ngModel)]="selectModel.author">
<div class="text-danger" *ngIf="!selectModel.author">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label for="createdDate" class="form-label">{{'วันที่สร้าง' | translate}}</label>
<input type="datetime-local" class="form-control" id="createdDate" placeholder=""
[(ngModel)]="selectModel.createdDate">
<div class="text-danger" *ngIf="!selectModel.createdDate">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label for="lastModifiedDate" class="form-label">{{'วันที่เเก้ไขล่าสุด' | translate}}</label>
<input type="datetime-local" class="form-control" id="lastModifiedDate" placeholder=""
[(ngModel)]="selectModel.lastModifiedDate">
<div class="text-danger" *ngIf="!selectModel.lastModifiedDate">
{{'Please fill in information' | translate}}
</div>
</div>
</div>
</div>
<div class="ti-modal-footer">
<button type="button" class="hs-dropdown-toggle ti-btn ti-btn-light align-middle"
data-hs-overlay="#modal-detail">
{{'Cancel' | translate}}
</button>
<button type="button" (click)="save()" class="ti-btn bg-primary text-white !font-medium">{{'Save' |
translate}}
</button>
</div>
</div>
</div>
</div> -->
\ No newline at end of file
src/app/DPU/common/article-manage/article-manage.component.ts
0 → 100644
View file @
a2ae82b1
import
{
Component
,
ElementRef
,
ViewChild
}
from
'@angular/core'
;
import
{
DomSanitizer
,
SafeHtml
}
from
'@angular/platform-browser'
;
import
{
Router
,
RouterModule
}
from
'@angular/router'
;
import
{
SharedModule
}
from
'../../../shared/shared.module'
;
import
{
TranslateModule
,
TranslateService
}
from
'@ngx-translate/core'
;
import
swal
from
'sweetalert'
;
import
{
MatPaginator
}
from
'@angular/material/paginator'
;
import
{
FormsModule
}
from
'@angular/forms'
;
import
{
NgSelectModule
}
from
'@ng-select/ng-select'
;
import
{
CommonModule
}
from
'@angular/common'
;
import
{
FileUploadModule
}
from
'ng2-file-upload'
;
import
{
FileItem
,
FileUploader
,
ParsedResponseHeaders
}
from
"ng2-file-upload"
;
import
{
environment
}
from
'../../../../environments/environment'
;
import
{
TokenService
}
from
'../../../shared/services/token.service'
import
{
ArticleModel
}
from
'../../models/article.model'
;
import
{
ArticleService
}
from
'../../services/article.service'
;
import
{
QuillModule
}
from
'ngx-quill'
;
import
{
MatDialog
,
MatDialogModule
}
from
'@angular/material/dialog'
;
@
Component
({
selector
:
'app-article-manage'
,
standalone
:
true
,
imports
:
[
CommonModule
,
SharedModule
,
TranslateModule
,
NgSelectModule
,
FormsModule
,
MatPaginator
,
RouterModule
,
FileUploadModule
,
QuillModule
,
MatDialogModule
],
templateUrl
:
'./article-manage.component.html'
,
styleUrl
:
'./article-manage.component.css'
,
})
export
class
ArticleManageComponent
{
quillConfig
=
{
toolbar
:
[
[
'link'
],
// เพิ่มปุ่มลิงก์
[
'bold'
,
'italic'
,
'underline'
,
'strike'
],
// toggled buttons
[
'blockquote'
,
'code-block'
],
[{
'header'
:
1
},
{
'header'
:
2
}],
// custom button values
[{
'list'
:
'ordered'
},
{
'list'
:
'bullet'
}],
[{
'script'
:
'sub'
},
{
'script'
:
'super'
}],
// superscript/subscript
[{
'indent'
:
'-1'
},
{
'indent'
:
'+1'
}],
// outdent/indent
[{
'direction'
:
'rtl'
}],
// text direction
[{
'size'
:
[
'small'
,
false
,
'large'
,
'huge'
]
}],
// custom dropdown
[{
'header'
:
[
1
,
2
,
3
,
4
,
5
,
6
,
false
]
}],
[{
'color'
:
[]
},
{
'background'
:
[]
}],
// dropdown with defaults from theme
[{
'align'
:
[]
}],
[
'clean'
],
// remove formatting button
]
};
@
ViewChild
(
'closeModal'
)
public
childModal
?:
ElementRef
;
@
ViewChild
(
'modalDetail'
)
public
modalDetail
?:
ElementRef
;
@
ViewChild
(
"articleModel"
)
articleModel
:
any
;
dialogRef
:
any
action
=
"new"
;
allSelected
=
false
;
someSelected
=
false
;
itemsList
:
ArticleModel
[]
=
[];
filterList
:
ArticleModel
[]
=
[];
selectModel
:
ArticleModel
=
new
ArticleModel
();
selectedItems
=
new
Map
<
string
,
boolean
>
();
editorInstance
:
any
;
// empList: ArticleModel[] = [];
// descName = 'engName';
pageIndex
=
0
;
uploaderProfile
:
FileUploader
|
undefined
;
uploadErrorMsg
:
string
=
""
;
get
searchTerm
():
string
{
return
this
.
_searchTerm
;
}
set
searchTerm
(
val
:
string
)
{
this
.
pageIndex
=
0
;
this
.
allSelected
=
false
;
this
.
_searchTerm
=
val
;
if
(
val
!=
''
)
{
this
.
filterList
=
this
.
filter
(
val
);
}
else
{
this
.
updatePagedItems
();
}
}
_searchTerm
=
""
;
constructor
(
private
articleService
:
ArticleService
,
public
translate
:
TranslateService
,
private
tokenService
:
TokenService
,
private
router
:
Router
,
private
dialog
:
MatDialog
,)
{
this
.
uploadConfig
();
}
isDescriptionValid
():
boolean
{
const
plainText
=
this
.
editorInstance
?.
getText
()?.
trim
()
||
''
;
return
plainText
.
length
>
0
;
}
onEditorCreated
(
quill
:
any
)
{
this
.
editorInstance
=
quill
;
}
onContentChanged
(
event
:
any
)
{
const
text
=
event
.
editor
.
getText
().
trim
();
if
(
text
.
length
===
0
&&
this
.
editorInstance
)
{
this
.
editorInstance
.
formatLine
(
0
,
1
,
'header'
,
false
);
}
this
.
selectModel
.
content
=
event
.
html
;
}
uploadConfig
()
{
this
.
uploaderProfile
=
new
FileUploader
({
url
:
environment
.
baseUrl
+
"/api/upload-image"
,
isHTML5
:
true
,
authToken
:
this
.
tokenService
.
getToken
()
!
,
});
this
.
uploaderProfile
.
onAfterAddingFile
=
(
fileItem
:
FileItem
)
=>
{
fileItem
.
withCredentials
=
false
;
this
.
uploadErrorMsg
=
""
;
while
(
this
.
uploaderProfile
!
.
queue
.
length
>
1
)
{
this
.
uploaderProfile
!
.
queue
[
0
].
remove
();
}
if
(
fileItem
.
file
.
size
>
5000000
)
{
this
.
uploadErrorMsg
=
"maximum file size 5mb."
;
swal
(
"Opp!!"
,
"ไม่สามารถอัพโหลดได้"
,
"info"
);
fileItem
.
isCancel
=
true
;
return
;
}
if
(
fileItem
.
file
.
type
!
.
indexOf
(
"image"
)
===
-
1
)
{
this
.
uploadErrorMsg
=
"please upload image only."
;
swal
(
"Opp!!"
,
"ไม่สามารถอัพโหลดได้"
,
"info"
);
fileItem
.
isCancel
=
true
;
return
;
}
fileItem
.
upload
();
};
this
.
uploaderProfile
.
onCompleteItem
=
(
item
:
FileItem
,
response
:
string
,
status
:
number
,
headers
:
ParsedResponseHeaders
)
=>
{
if
(
item
.
isSuccess
)
{
const
res
=
JSON
.
parse
(
response
);
console
.
log
(
"res"
,
res
);
this
.
selectModel
.
picture
=
res
.
filename
;
swal
(
res
.
message
,
"บันทึกสำเร็จ"
,
"success"
);
}
else
{
this
.
uploadErrorMsg
=
"cannot upload file."
;
swal
(
"Opp!!"
,
"ไม่สามารถอัพโหลดได้"
,
"info"
);
}
};
}
getArticle
()
{
this
.
articleService
.
getList
().
subscribe
({
next
:
(
response
:
ArticleModel
[])
=>
{
this
.
itemsList
=
response
.
map
((
x
:
any
)
=>
new
ArticleModel
(
x
,
this
.
translate
));
console
.
log
(
'ข้อมูลบริษัท (itemsList)'
,
this
.
itemsList
);
this
.
updatePagedItems
();
},
error
:
(
error
)
=>
{
console
.
error
(
'error cant get company'
,
error
);
swal
(
"ข้อผิดพลาด"
,
"ไม่สามารถดึงข้อมูลบริษัทได้"
,
"error"
);
}
});
}
ngOnInit
():
void
{
this
.
getArticle
();
this
.
itemsList
}
filter
(
v
:
string
)
{
return
this
.
itemsList
?.
filter
(
(
x
)
=>
x
.
articleId
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
title
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
content
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
excerpt
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
author
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
// x.getStatus().toLowerCase().indexOf(v.toLowerCase()) !== -1
);
}
delete
(
item
:
ArticleModel
)
{
swal
({
title
:
"คุณแน่ใจหรือไม่?"
,
text
:
"คุณจะไม่สามารถกู้คืนข้อมูลนี้ได้!"
,
icon
:
"warning"
,
dangerMode
:
true
,
buttons
:
[
"ยกเลิก"
,
"ใช่, ลบเลย!"
],
})
.
then
((
willDelete
:
any
)
=>
{
if
(
willDelete
)
{
this
.
articleService
.
deletearticle
(
item
).
subscribe
(
result
=>
{
swal
(
"ลบสำเร็จ!!"
,
"ลบข้อมูลสำเร็จ"
,
"success"
);
this
.
ngOnInit
();
},
error
=>
{
console
.
error
(
"เกิดข้อผิดพลาดในการลบ:"
,
error
);
swal
(
"ข้อผิดพลาด!!"
,
"ไม่สามารถลบข้อมูลได้"
,
"error"
);
});
}
});
}
new
()
{
this
.
action
=
'add'
;
this
.
selectModel
=
new
ArticleModel
();
// this.selectModel.status = 1;
this
.
selectModel
.
excerpt
=
""
;
this
.
selectModel
.
picture
=
""
;
this
.
selectModel
.
title
=
""
;
this
.
selectModel
.
articleId
=
""
;
this
.
selectModel
.
content
=
""
;
this
.
selectModel
.
author
=
""
;
this
.
selectModel
.
createdDate
=
new
Date
().
toISOString
();
}
view
(
item
:
ArticleModel
)
{
this
.
action
=
'edit'
;
this
.
selectModel
=
new
ArticleModel
(
item
);
console
.
log
(
this
.
selectModel
);
}
viewArticleDetail
(
articleId
:
string
)
{
this
.
router
.
navigate
([
'/admin/sub-articles'
,
articleId
]);
}
save
()
{
swal
({
title
:
"คุณแน่ใจหรือไม่?"
,
text
:
"คุณต้องการบันทึกหรือไม่"
,
icon
:
"warning"
,
dangerMode
:
false
,
buttons
:
[
"ยกเลิก"
,
"ยืนยัน"
],
})
.
then
((
willSave
:
any
)
=>
{
if
(
willSave
)
{
this
.
articleService
.
postArticle
(
this
.
selectModel
).
subscribe
(
result
=>
{
console
.
log
(
result
);
swal
(
"บันทึกสำเร็จ!!"
,
"บันทึกข้อมูลสมาชิก"
,
"success"
);
this
.
ngOnInit
();
this
.
childModal
?.
nativeElement
.
click
();
},
error
=>
{
console
.
error
(
"เกิดข้อผิดพลาดในการบันทึก/อัปเดต:"
,
error
);
swal
(
"ข้อผิดพลาด!!"
,
"ไม่สามารถบันทึก/อัปเดตข้อมูลได้"
,
"error"
);
});
}
});
}
updatePagedItems
()
{
const
startIndex
=
this
.
pageIndex
*
10
;
const
endIndex
=
startIndex
+
10
;
this
.
filterList
=
this
.
itemsList
.
slice
(
startIndex
,
endIndex
);
}
toggleAll
(
event
:
any
)
{
this
.
allSelected
=
event
.
target
.
checked
;
this
.
selectedItems
.
clear
();
this
.
itemsList
.
forEach
(
item
=>
{
this
.
selectedItems
.
set
(
item
.
articleId
,
this
.
allSelected
);
});
this
.
someSelected
=
this
.
itemsList
.
some
(
item
=>
this
.
selectedItems
.
get
(
item
.
articleId
));
}
onCheckboxChange
(
articleId
:
string
)
{
const
isSelected
=
this
.
selectedItems
.
get
(
articleId
)
||
false
;
this
.
selectedItems
.
set
(
articleId
,
!
isSelected
);
this
.
allSelected
=
this
.
itemsList
.
every
(
item
=>
this
.
selectedItems
.
get
(
item
.
articleId
));
this
.
someSelected
=
this
.
itemsList
.
some
(
item
=>
this
.
selectedItems
.
get
(
item
.
articleId
));
}
deleteSelect
()
{
let
companyInfo
=
''
;
const
selectedarticleIdsToDelete
:
string
[]
=
[];
this
.
selectedItems
.
forEach
((
isSelected
,
articleId
)
=>
{
if
(
isSelected
)
{
const
item
=
this
.
itemsList
.
find
(
c
=>
c
.
articleId
===
articleId
);
if
(
item
)
{
companyInfo
+=
`
${
this
.
translate
.
instant
(
'บริษัท'
)}
:
${
item
.
title
}
\n`
;
selectedarticleIdsToDelete
.
push
(
item
.
articleId
);
}
}
});
if
(
selectedarticleIdsToDelete
.
length
===
0
)
{
swal
(
"ข้อผิดพลาด"
,
"กรุณาเลือกบริษัทที่ต้องการลบ"
,
"warning"
);
return
;
}
swal
({
title
:
"คุณแน่ใจหรือไม่?"
,
text
:
companyInfo
,
icon
:
"warning"
,
dangerMode
:
true
,
buttons
:
[
"ยกเลิก"
,
"ใช่, ลบเลย!"
],
})
.
then
((
willDelete
:
any
)
=>
{
if
(
willDelete
)
{
const
deletePromises
=
selectedarticleIdsToDelete
.
map
(
articleId
=>
this
.
articleService
.
deletearticleById
(
articleId
).
toPromise
()
.
then
(()
=>
true
)
.
catch
(
error
=>
{
console
.
error
(
`Error deleting company
${
articleId
}
:`
,
error
);
return
false
;
})
);
Promise
.
all
(
deletePromises
)
.
then
(
results
=>
{
const
allSuccessful
=
results
.
every
(
success
=>
success
);
if
(
allSuccessful
)
{
swal
(
"ลบสำเร็จ!!"
,
"บันทึกข้อมูลสำเร็จ"
,
"success"
);
}
else
{
swal
(
"สำเร็จบางส่วน/ข้อผิดพลาด!!"
,
"มีการลบข้อมูลบางส่วนไม่สำเร็จ หรือมีข้อผิดพลาด"
,
"warning"
);
}
this
.
ngOnInit
();
this
.
selectedItems
.
clear
();
this
.
allSelected
=
false
;
this
.
someSelected
=
false
;
});
}
});
}
adjustSelect
(
status
:
number
)
{
// เพิ่ม status เข้ามาในพารามิเตอร์
let
title
=
"คุณแน่ใจหรือไม่?"
;
let
companyInfo
=
''
;
const
selectedCompanies
:
ArticleModel
[]
=
[];
this
.
selectedItems
.
forEach
((
isSelected
,
articleId
)
=>
{
if
(
isSelected
)
{
const
company
=
this
.
itemsList
.
find
(
c
=>
c
.
articleId
===
articleId
);
if
(
company
)
{
companyInfo
+=
`
${
this
.
translate
.
instant
(
'ชื่อบริษัท'
)}
:
${
company
.
title
}
\n`
;
selectedCompanies
.
push
(
company
);
}
}
});
if
(
selectedCompanies
.
length
===
0
)
{
swal
(
"ข้อผิดพลาด"
,
"กรุณาเลือกบริษัทที่ต้องการปรับสถานะ"
,
"warning"
);
return
;
}
swal
({
title
:
title
,
text
:
companyInfo
,
icon
:
"warning"
,
dangerMode
:
false
,
buttons
:
[
"ยกเลิก"
,
"ยืนยัน"
],
})
.
then
((
willAdjust
:
any
)
=>
{
if
(
willAdjust
)
{
const
updatePromises
=
selectedCompanies
.
map
(
company
=>
{
company
.
publish
=
status
;
// เปลี่ยนจาก publish เป็น status
return
this
.
articleService
.
postArticle
(
company
).
toPromise
()
.
then
(()
=>
true
)
.
catch
(
error
=>
{
console
.
error
(
`Error updating publish for company
${
company
.
articleId
}
:`
,
error
);
return
false
;
});
});
Promise
.
all
(
updatePromises
)
.
then
(
results
=>
{
const
allSuccessful
=
results
.
every
(
success
=>
success
);
if
(
allSuccessful
)
{
swal
(
"บันทึกสำเร็จ!!"
,
"บันทึกข้อมูลสำเร็จ"
,
"success"
);
}
else
{
swal
(
"สำเร็จบางส่วน/ข้อผิดพลาด!!"
,
"มีการอัปเดตสถานะบางส่วนไม่สำเร็จ หรือมีข้อผิดพลาด"
,
"warning"
);
}
this
.
ngOnInit
();
this
.
selectedItems
.
clear
();
this
.
allSelected
=
false
;
this
.
someSelected
=
false
;
});
}
});
}
openDialog
()
{
this
.
dialogRef
=
this
.
dialog
.
open
(
this
.
articleModel
,
{
width
:
'1100px'
,
disableClose
:
false
,
});
}
closeDialog
()
{
this
.
dialogRef
.
close
()
}
}
\ No newline at end of file
src/app/DPU/common/common.module.ts
View file @
a2ae82b1
...
...
@@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common';
import
{
CommonComponent
}
from
'./common.component'
;
import
{
RouterModule
,
Routes
}
from
'@angular/router'
;
import
{
SharedModule
}
from
'../../shared/shared.module'
;
import
{
QuillModule
}
from
'ngx-quill'
;
export
const
admin
:
Routes
=
[
{
path
:
'admin'
,
children
:
[{
...
...
@@ -21,6 +22,11 @@ export const admin: Routes = [
import
(
'./company-manage/company-manage.component'
).
then
((
m
)
=>
m
.
CompanyManageComponent
),
},
{
path
:
'manage-articles'
,
loadComponent
:
()
=>
import
(
'./article-manage/article-manage.component'
).
then
((
m
)
=>
m
.
ArticleManageComponent
),
},
{
path
:
'admin-manage'
,
loadComponent
:
()
=>
import
(
'./admin-manage/admin-manage.component'
).
then
((
m
)
=>
m
.
AdminManageComponent
),
...
...
@@ -54,7 +60,8 @@ export const admin: Routes = [
@
NgModule
({
imports
:
[
CommonModule
,
RouterModule
.
forChild
(
admin
)
RouterModule
.
forChild
(
admin
),
QuillModule
.
forRoot
(),
],
exports
:
[
RouterModule
],
declarations
:
[
CommonComponent
]
...
...
src/app/DPU/models/article.model.ts
0 → 100644
View file @
a2ae82b1
import
{
TranslateService
}
from
"@ngx-translate/core"
import
{
BaseModel
,
dataToArray
}
from
"./base.model"
import
{
CompanyModel
}
from
"./company.model"
import
{
environment
}
from
"../../../environments/environment"
;
export
interface
ArticleModel
{
articleId
:
string
companyId
:
CompanyModel
[]
title
:
string
content
:
string
excerpt
:
string
category
:
string
author
:
string
picture
:
string
createdDate
:
string
lastModifiedDate
:
string
publish
:
number
viewCount
:
number
}
export
class
ArticleModel
extends
BaseModel
implements
ArticleModel
{
articleId
:
string
companyId
:
CompanyModel
[]
title
:
string
content
:
string
excerpt
:
string
category
:
string
author
:
string
picture
:
string
createdDate
:
string
lastModifiedDate
:
string
publish
:
number
viewCount
:
number
constructor
(
data
?:
Partial
<
ArticleModel
>
,
translateService
?:
TranslateService
)
{
super
(
data
,
translateService
)
this
.
articleId
=
data
?.
articleId
!
this
.
companyId
=
dataToArray
(
data
?.
companyId
).
map
((
x
:
CompanyModel
)
=>
new
CompanyModel
(
x
,
translateService
))
this
.
title
=
data
?.
title
!
this
.
content
=
data
?.
content
!
this
.
excerpt
=
data
?.
excerpt
!
this
.
category
=
data
?.
category
!
this
.
author
=
data
?.
author
!
this
.
picture
=
data
?.
picture
!
this
.
createdDate
=
data
?.
createdDate
!
this
.
lastModifiedDate
=
data
?.
lastModifiedDate
!
this
.
publish
=
data
?.
publish
!
this
.
viewCount
=
data
?.
viewCount
!
}
getPicture
():
string
{
if
(
this
.
picture
)
{
return
environment
.
baseUrl
+
"/files/image/"
+
this
.
picture
}
else
{
return
""
}
}
}
src/app/DPU/services/article.service.ts
0 → 100644
View file @
a2ae82b1
import
{
HttpClient
,
HttpHeaders
}
from
'@angular/common/http'
;
import
{
Injectable
}
from
'@angular/core'
;
import
{
Observable
}
from
'rxjs'
;
import
{
environment
}
from
"../../../environments/environment"
;
import
{
CompanyModelS
}
from
'../models/companys.mode'
;
import
{
ArticleModel
}
from
'../models/article.model'
;
@
Injectable
({
providedIn
:
'root'
})
export
class
ArticleService
{
api
=
"/article"
urlApi
=
environment
.
baseUrl
+
"/article"
constructor
(
private
http
:
HttpClient
)
{
}
getById
(
articleId
:
string
):
Observable
<
ArticleModel
>
{
return
this
.
http
.
get
<
ArticleModel
>
(
this
.
urlApi
+
"/"
+
articleId
)
}
getList
():
Observable
<
ArticleModel
[]
>
{
return
this
.
http
.
get
<
ArticleModel
[]
>
(
this
.
urlApi
+
"/lists"
)
}
getListByCompany
(
companyId
:
CompanyModelS
[]):
Observable
<
ArticleModel
[]
>
{
return
this
.
http
.
get
<
ArticleModel
[]
>
(
this
.
urlApi
+
"/lists/"
+
companyId
);
}
postArticle
(
body
:
ArticleModel
):
Observable
<
any
>
{
return
this
.
http
.
post
(
this
.
urlApi
,
body
)
}
deletearticle
(
body
:
ArticleModel
)
{
const
options
=
{
headers
:
new
HttpHeaders
({
"Content-Type"
:
"application/json"
,
}),
body
:
body
,
};
return
this
.
http
.
delete
(
this
.
urlApi
,
options
)
}
deletearticleById
(
articleId
:
string
)
{
const
options
=
{
headers
:
new
HttpHeaders
({
"Content-Type"
:
"application/json"
,
}),
body
:
{
articleId
:
articleId
},
};
return
this
.
http
.
delete
(
this
.
urlApi
,
options
)
}
}
src/app/shared/services/nav.service.ts
View file @
a2ae82b1
...
...
@@ -109,6 +109,13 @@ export class NavService implements OnDestroy {
},
{
icon
:
'buildings'
,
path
:
'/admin/manage-articles'
,
title
:
'จัดการบทความ'
,
type
:
'link'
,
},
{
icon
:
'user-check'
,
path
:
'/admin/admin-manage'
,
title
:
'จัดการสิทธิ์ผู้ดูแลระบบ'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment