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
You need to sign in or sign up before continuing.
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
Show 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
...
...
@@ -10,7 +10,7 @@ export interface Job {
type
:
JobType
;
created_at
:
string
;
how_to_apply
?:
string
;
company_logo
?:
string
|
null
;
company_logo
?:
string
;
}
export
type
JobLocation
=
'Viet Nam'
|
'Lao'
|
'Campuchia'
;
...
...
@@ -25,7 +25,7 @@ export interface JobFormData {
location
:
JobLocation
;
type
:
JobType
;
how_to_apply
?:
string
;
company_logo
?:
string
|
null
;
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
;
});
if
(
jobFound
)
{
this
.
setJobs
(
updatedJobs
);
this
.
updateStats
();
console
.
log
(
'Jobs after update:'
,
this
.
jobsSignal
().
length
);
}
};
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