Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
Meu-Template-Angular-CSR
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
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
Trần Anh Phú
Meu-Template-Angular-CSR
Commits
c65fa1c8
Commit
c65fa1c8
authored
Jul 13, 2025
by
Nguyễn Thị Thanh Trúc
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix job update
parent
53209eb3
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
56 additions
and
67 deletions
+56
-67
dashboard.component.ts
src/app/+admin/pages/dashboard/dashboard.component.ts
+10
-15
job.interface.ts
src/app/shared/data-access/interface/job.interface.ts
+5
-5
job-api.service.ts
src/app/shared/data-access/service/job-api.service.ts
+25
-34
job-state.service.ts
src/app/shared/data-access/service/job-state.service.ts
+16
-13
No files found.
src/app/+admin/pages/dashboard/dashboard.component.ts
View file @
c65fa1c8
...
...
@@ -287,7 +287,6 @@ export class DashboardComponent implements OnInit {
console
.
log
(
'Jobs loaded successfully from API'
);
},
error
:
(
error
)
=>
{
console
.
error
(
'Failed to load jobs from API:'
,
error
);
this
.
messageService
.
error
(
`Failed to load jobs:
${
error
.
message
}
`
);
}
});
...
...
@@ -320,7 +319,6 @@ export class DashboardComponent implements OnInit {
viewJobDetail
(
job
:
Job
):
void
{
this
.
selectedJob
=
job
;
this
.
showDetailModal
=
true
;
console
.
log
(
'Opening job detail for:'
,
job
.
title
);
this
.
cdr
.
markForCheck
();
}
...
...
@@ -371,10 +369,8 @@ export class DashboardComponent implements OnInit {
}
closeDetailModal
():
void
{
console
.
log
(
'Closing detail modal...'
);
this
.
showDetailModal
=
false
;
this
.
selectedJob
=
null
;
console
.
log
(
'Detail modal closed, state reset'
);
this
.
cdr
.
markForCheck
();
}
...
...
@@ -391,15 +387,18 @@ export class DashboardComponent implements OnInit {
this
.
cdr
.
markForCheck
();
if
(
this
.
isEditMode
&&
this
.
selectedJob
)
{
// Update job
console
.
log
(
'Updating job:'
,
this
.
selectedJob
.
id
,
'with data:'
,
jobData
);
this
.
jobApiService
.
updateJob
({
id
:
this
.
selectedJob
.
id
,
job
:
jobData
}).
subscribe
({
next
:
(
response
)
=>
{
console
.
log
(
'Update job response:'
,
response
);
if
(
response
.
success
)
{
this
.
jobStateService
.
updateJob
(
response
.
responseData
.
job
);
this
.
messageService
.
success
(
`Job "
${
response
.
responseData
.
job
.
title
}
" updated successfully`
);
if
(
response
.
success
&&
this
.
selectedJob
)
{
const
updatedJob
:
Job
=
{
...
this
.
selectedJob
,
...
response
.
responseData
.
job
,
id
:
this
.
selectedJob
.
id
,
created_at
:
this
.
selectedJob
.
created_at
};
this
.
jobStateService
.
updateJob
(
updatedJob
);
this
.
messageService
.
success
(
`Job "
${
updatedJob
.
title
}
" updated successfully`
);
this
.
closeJobFormModal
();
this
.
cdr
.
markForCheck
();
}
else
{
...
...
@@ -409,22 +408,18 @@ export class DashboardComponent implements OnInit {
}
},
error
:
(
error
)
=>
{
console
.
error
(
'Update job error:'
,
error
);
this
.
messageService
.
error
(
`Failed to update job:
${
error
.
message
}
`
);
this
.
jobFormLoading
.
set
(
false
);
this
.
cdr
.
markForCheck
();
}
});
}
else
{
// Create new job
this
.
jobApiService
.
createJob
({
job
:
jobData
}).
subscribe
({
next
:
(
response
)
=>
{
if
(
response
.
success
)
{
console
.
log
(
'Job created successfully, response:'
,
response
);
this
.
jobStateService
.
addJob
(
response
.
responseData
.
job
);
this
.
messageService
.
success
(
`Job "
${
response
.
responseData
.
job
.
title
}
" created successfully`
);
this
.
closeJobFormModal
();
this
.
cdr
.
markForCheck
();
setTimeout
(()
=>
{
...
...
src/app/shared/data-access/interface/job.interface.ts
View file @
c65fa1c8
...
...
@@ -9,8 +9,8 @@ export interface Job {
location
:
string
;
type
:
JobType
;
created_at
:
string
;
how_to_apply
?:
string
;
company_logo
?:
string
|
null
;
how_to_apply
?:
string
;
company_logo
?:
string
;
}
export
type
JobLocation
=
'Viet Nam'
|
'Lao'
|
'Campuchia'
;
...
...
@@ -24,8 +24,8 @@ export interface JobFormData {
company_url
:
string
;
location
:
JobLocation
;
type
:
JobType
;
how_to_apply
?:
string
;
company_logo
?:
string
|
null
;
how_to_apply
?:
string
;
company_logo
?:
string
;
}
export
interface
CreateJobRequest
{
...
...
@@ -34,7 +34,7 @@ export interface CreateJobRequest {
export
interface
UpdateJobRequest
{
id
:
string
;
job
:
Partial
<
JobFormData
>
;
job
:
JobFormData
;
}
export
interface
JobResponse
{
...
...
src/app/shared/data-access/service/job-api.service.ts
View file @
c65fa1c8
...
...
@@ -33,6 +33,8 @@ interface ApiJob {
location
:
string
;
title
:
string
;
description
:
string
;
how_to_apply
?:
string
;
company_logo
?:
string
;
}
@
Injectable
({
providedIn
:
'root'
})
...
...
@@ -71,22 +73,12 @@ export class JobApiService {
};
private
convertApiJobToJob
=
(
apiJob
:
ApiJob
):
Job
=>
{
console
.
log
(
'Converting API job to internal format:'
,
apiJob
);
const
job
:
Job
=
{
id
:
apiJob
.
id
||
''
,
title
:
apiJob
.
title
||
''
,
description
:
apiJob
.
description
||
''
,
company
:
apiJob
.
company
||
''
,
company_url
:
apiJob
.
company_url
||
''
,
location
:
apiJob
.
location
||
''
,
...
apiJob
,
type
:
this
.
mapApiTypeToJobType
(
apiJob
.
type
),
created_at
:
apiJob
.
created_at
||
new
Date
().
toISOString
(),
how_to_apply
:
""
,
company_logo
:
null
};
console
.
log
(
'Converted job:'
,
job
);
return
job
;
};
...
...
@@ -127,27 +119,23 @@ export class JobApiService {
createJob
=
(
request
:
CreateJobRequest
):
Observable
<
JobResponse
>
=>
{
console
.
log
(
'Creating job with request:'
,
request
);
const
apiJobData
=
{
title
:
request
.
job
.
title
,
description
:
request
.
job
.
description
,
company
:
request
.
job
.
company
,
company_url
:
request
.
job
.
company_url
,
location
:
request
.
job
.
location
,
type
:
request
.
job
.
type
type
:
request
.
job
.
type
,
how_to_apply
:
request
.
job
.
how_to_apply
,
company_logo
:
request
.
job
.
company_logo
,
};
console
.
log
(
'Sending API data:'
,
apiJobData
);
return
this
.
http
.
post
<
ApiJob
>
(
this
.
API_URL
,
apiJobData
,
{
headers
:
this
.
getHeaders
()
}).
pipe
(
map
(
apiJob
=>
{
console
.
log
(
'Received API response:'
,
apiJob
);
const
convertedJob
=
this
.
convertApiJobToJob
(
apiJob
);
const
result
=
{
return
{
message
:
'Job created successfully'
,
responseData
:
{
job
:
convertedJob
...
...
@@ -155,9 +143,6 @@ export class JobApiService {
success
:
true
,
status
:
201
};
console
.
log
(
'Final response:'
,
result
);
return
result
;
}),
catchError
(
this
.
handleError
)
);
...
...
@@ -173,20 +158,31 @@ export class JobApiService {
company
:
request
.
job
.
company
,
company_url
:
request
.
job
.
company_url
,
location
:
request
.
job
.
location
,
type
:
request
.
job
.
type
type
:
request
.
job
.
type
,
how_to_apply
:
request
.
job
.
how_to_apply
,
company_logo
:
request
.
job
.
company_logo
,
};
console
.
log
(
'Sending update API data:'
,
apiJobData
);
console
.
log
(
'Update URL:'
,
`
${
this
.
API_URL
}
/
${
request
.
id
}
`
);
return
this
.
http
.
put
<
ApiJob
>
(
`
${
this
.
API_URL
}
/
${
request
.
id
}
`
,
apiJobData
,
{
headers
:
this
.
getHeaders
()
}).
pipe
(
map
(
apiJob
=>
{
console
.
log
(
'Received update API response:'
,
apiJob
);
const
apiJobWithId
:
ApiJob
=
{
...
apiJob
,
id
:
apiJob
.
id
||
request
.
id
,
created_at
:
apiJob
.
created_at
||
new
Date
().
toISOString
(),
title
:
apiJob
.
title
||
request
.
job
.
title
,
description
:
apiJob
.
description
||
request
.
job
.
description
,
company
:
apiJob
.
company
||
request
.
job
.
company
,
company_url
:
apiJob
.
company_url
||
request
.
job
.
company_url
,
location
:
apiJob
.
location
||
request
.
job
.
location
,
type
:
apiJob
.
type
||
request
.
job
.
type
,
how_to_apply
:
apiJob
.
how_to_apply
||
request
.
job
.
how_to_apply
,
company_logo
:
apiJob
.
company_logo
||
request
.
job
.
company_logo
,
};
const
convertedJob
=
this
.
convertApiJobToJob
(
apiJob
);
const
result
=
{
const
convertedJob
=
this
.
convertApiJobToJob
(
apiJob
WithId
);
return
{
message
:
'Job updated successfully'
,
responseData
:
{
job
:
convertedJob
...
...
@@ -194,9 +190,6 @@ export class JobApiService {
success
:
true
,
status
:
200
};
console
.
log
(
'Final update response:'
,
result
);
return
result
;
}),
catchError
(
this
.
handleError
)
);
...
...
@@ -214,7 +207,6 @@ export class JobApiService {
);
getJobStats
=
():
Observable
<
{
success
:
boolean
;
data
:
JobStats
}
>
=>
{
// Since the API doesn't provide stats endpoint, we'll calculate from jobs
return
this
.
getJobs
().
pipe
(
map
(
response
=>
{
const
jobs
=
response
.
responseData
.
jobs
;
...
...
@@ -228,7 +220,6 @@ export class JobApiService {
};
}),
catchError
(
error
=>
{
console
.
error
(
'Failed to get job stats:'
,
error
);
return
of
({
success
:
false
,
data
:
{
...
...
src/app/shared/data-access/service/job-state.service.ts
View file @
c65fa1c8
...
...
@@ -61,34 +61,37 @@ export class JobStateService {
};
addJob
=
(
job
:
Job
):
void
=>
{
console
.
log
(
'Adding new job to state:'
,
job
);
const
currentJobs
=
this
.
jobsSignal
();
console
.
log
(
'Current jobs before adding:'
,
currentJobs
.
length
);
const
updatedJobs
=
[
job
,
...
currentJobs
];
this
.
setJobs
(
updatedJobs
);
this
.
updateStats
();
console
.
log
(
'Jobs after adding:'
,
this
.
jobsSignal
().
length
);
};
updateJob
=
(
updatedJob
:
Job
):
void
=>
{
console
.
log
(
'Updating job in state:'
,
updatedJob
);
if
(
!
updatedJob
.
id
)
{
return
;
}
const
currentJobs
=
this
.
jobsSignal
();
console
.
log
(
'Current jobs before update:'
,
currentJobs
.
length
)
;
let
jobFound
=
false
;
const
updatedJobs
=
currentJobs
.
map
(
job
=>
{
if
(
job
.
id
===
updatedJob
.
id
)
{
console
.
log
(
'Found job to update:'
,
job
.
id
);
return
updatedJob
;
jobFound
=
true
;
return
{
...
job
,
...
updatedJob
,
id
:
job
.
id
,
created_at
:
job
.
created_at
};
}
return
job
;
});
this
.
setJobs
(
updatedJobs
);
this
.
updateStats
(
);
console
.
log
(
'Jobs after update:'
,
this
.
jobsSignal
().
length
);
if
(
jobFound
)
{
this
.
setJobs
(
updatedJobs
);
this
.
updateStats
();
}
};
removeJob
=
(
jobId
:
string
):
void
=>
{
...
...
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