From f4625e0f6686995e0a8ea22ba5374784a4e513bb Mon Sep 17 00:00:00 2001 From: nekorpeche Date: Mon, 29 Nov 2021 19:46:57 +0100 Subject: [PATCH] RI-192: [admin/front] permet d'archiver plusieurs offres depuis le listing d'offres * code review * suppression composant jobs-table --- .../app/admin/jobs/admin-jobs.component.html | 92 ++++++++++- .../app/admin/jobs/admin-jobs.component.scss | 13 ++ .../app/admin/jobs/admin-jobs.component.ts | 145 +++++++++++++++++- .../src/app/admin/jobs/admin-jobs.module.ts | 2 - .../jobs-table/jobs-table.component.scss | 13 -- .../jobs-table/jobs-table.component.spec.ts | 25 --- 6 files changed, 240 insertions(+), 50 deletions(-) delete mode 100644 frontend-implicaction/src/app/admin/jobs/components/jobs-table/jobs-table.component.scss delete mode 100644 frontend-implicaction/src/app/admin/jobs/components/jobs-table/jobs-table.component.spec.ts diff --git a/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.html b/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.html index 552bb908..08f690bc 100644 --- a/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.html +++ b/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.html @@ -12,20 +12,106 @@
Toutes les offres d'emplois
> - + + + + + + + Nom + Type + Localisation + Description + Actions + + + + + + + + + {{job.title}} + {{job.contractType?.label}} + {{job.location}} + {{job.description}} + +
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+ + +
+
+ diff --git a/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.scss b/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.scss index e69de29b..f3dfcba3 100644 --- a/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.scss +++ b/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.scss @@ -0,0 +1,13 @@ +::ng-deep { + .p-datatable .p-datatable-tbody > tr > td { + border-width: 0 !important; + } + + .p-datatable-thead { + + th { + background-color: transparent !important; + border: 0 !important; + } + } +} diff --git a/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.ts b/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.ts index 5138faba..ea15c0ba 100644 --- a/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.ts +++ b/frontend-implicaction/src/app/admin/jobs/admin-jobs.component.ts @@ -1,20 +1,147 @@ -import {Component, ViewChild} from '@angular/core'; +import {Component, OnInit} from '@angular/core'; import {SidebarService} from '../../shared/services/sidebar.service'; import {JobPostingFormComponent} from './components/job-posting-form/job-posting-form.component'; -import {JobsTableComponent} from './components/jobs-table/jobs-table.component'; +import {BaseWithPaginationComponent} from '../../shared/components/base-with-pagination/base-with-pagination.component'; +import {JobPosting} from '../../shared/models/job-posting'; +import {JobCriteriaFilter} from '../../job/models/job-criteria-filter'; +import {Constants} from '../../config/constants'; +import {Pageable} from '../../shared/models/pageable'; +import {JobSortEnum} from '../../job/enums/job-sort.enum'; +import {SortDirectionEnum} from '../../shared/enums/sort-direction.enum'; +import {JobService} from '../../job/services/job.service'; +import {ToasterService} from '../../core/services/toaster.service'; +import {JobFilterContextService} from '../../job/services/job-filter-context.service'; +import {ActivatedRoute} from '@angular/router'; +import {finalize, take} from 'rxjs/operators'; @Component({ selector: 'app-job', templateUrl: './admin-jobs.component.html', styleUrls: ['./admin-jobs.component.scss'] }) -export class AdminJobsComponent { - @ViewChild(JobsTableComponent) - jobsTableComponent: JobsTableComponent; +export class AdminJobsComponent extends BaseWithPaginationComponent implements OnInit { + readonly ROWS_PER_PAGE_OPTIONS = Constants.ROWS_PER_PAGE_OPTIONS; + loading = true; // indique si les données sont en chargement + isArchiveEnabled: boolean; + isArchive: boolean; + selectedJobs: JobPosting[] = []; + + // Pagination + pageable: Pageable = Constants.PAGEABLE_DEFAULT; + orderByEnums = JobSortEnum.all(); + selectedOrder = JobSortEnum.DATE_DESC; + criteria: JobCriteriaFilter; + selectedOrderCode: string; + sortDirection = SortDirectionEnum; constructor( + private jobService: JobService, + private toastService: ToasterService, private sidebarService: SidebarService, + private filterService: JobFilterContextService, + protected route: ActivatedRoute ) { + super(route); + } + + ngOnInit(): void { + this.pageable.sortOrder = JobSortEnum.DATE_DESC.sortDirection; + this.pageable.sortBy = JobSortEnum.DATE_DESC.sortBy; + this.selectedOrderCode = JobSortEnum.DATE_DESC.code; + + this.filterService + .observe() + .subscribe(criteria => { + this.criteria = criteria; + const objectParam = this.buildQueryParams(); + this.filterService.updateRouteQueryParams(objectParam); + this.paginate(); + }); + + this.getFilterFromQueryParams().then(() => this.filterService.criteria = this.criteria); + } + + onSortChange({value}): void { + const selectedOrderField = JobSortEnum.from(value); + this.pageable.sortBy = selectedOrderField.sortBy; + this.pageable.sortOrder = selectedOrderField.sortDirection; + this.filterService.criteria = this.criteria; // on relance la recherche en updatant le filtre + } + + onSearchChange(): void { + this.filterService.criteria = this.criteria; + } + + protected innerPaginate(): void { + this.jobService + .getAllByCriteria(this.pageable, this.criteria) + .pipe( + take(1), + finalize(() => this.loading = false) + ) + .subscribe( + data => { + this.pageable.totalPages = data.totalPages; + this.pageable.rows = data.size; + this.pageable.totalElements = data.totalElements; + this.pageable.content = data.content; + }, + () => this.toastService.error('Oops', 'Une erreur est survenue lors de la récupération des données'), + ); + } + + editJob(job: JobPosting): void { + this.sidebarService + .open({ + title: `Editer une nouvelle offre d'emploi`, + input: {job}, + component: JobPostingFormComponent, + width: 650 + }); + } + + archiveJob(job: JobPosting): void { + this.jobService + .archiveJob(job.id) + .subscribe( + () => this.paginate(), + () => this.toastService.error('Oops', 'Une erreur est survenue'), + () => this.toastService.success('Succès', job.archive ? 'Offre désarchivée' : `Offre archivée`) + ); + } + + protected async getFilterFromQueryParams(): Promise { + // TODO: voir si y'a un moyen plus élégant avec typeof + const filterKeys = ['search', 'contractType']; + const pageableKeys = ['rows', 'page', 'sortOrder', 'sortBy']; + return new Promise(resolve => { + this.route + .queryParams + .subscribe(params => { + Object.entries(params) + .forEach(([key, value]) => { + if (filterKeys.includes(key)) { + this.criteria[key] = value; + } else if (pageableKeys.includes(key)) { + this.pageable[key] = value; + } + }); + return resolve(); + }); + }); + } + + archiveJobList(): void { + const jobsId = this.selectedJobs.map(job => job.id); + this.jobService + .toggleArchiveJobs(jobsId) + .subscribe( + () => this.paginate(), + () => this.toastService.error('Oops', 'Une erreur est survenue'), + () => this.toastService.success('Succès', 'Opération effectuée'), + ); + this.selectedJobs = []; + this.isArchiveEnabled = false; } onAddJob(): void { @@ -26,8 +153,12 @@ export class AdminJobsComponent { }); } - archive(): void { - this.jobsTableComponent.archiveJobList(); + onRowSelect(): void { + // on vérifie que tous les éléments sélectionné sont tous archivés ou désarchivés + this.isArchiveEnabled = this.selectedJobs.every(job => job.archive === this.selectedJobs[0].archive); + // on recherche si le bouton toggleArchive doit archiver ou désarchiver + this.isArchive = this.selectedJobs.length > 0 ? this.selectedJobs[0].archive : false; + } } diff --git a/frontend-implicaction/src/app/admin/jobs/admin-jobs.module.ts b/frontend-implicaction/src/app/admin/jobs/admin-jobs.module.ts index f9be2146..2f31963f 100644 --- a/frontend-implicaction/src/app/admin/jobs/admin-jobs.module.ts +++ b/frontend-implicaction/src/app/admin/jobs/admin-jobs.module.ts @@ -1,6 +1,5 @@ import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; -import {JobsTableComponent} from './components/jobs-table/jobs-table.component'; import {AdminJobsComponent} from './admin-jobs.component'; import {AdminJobsRoutingModule} from './admin-jobs-routing.module'; import {TableModule} from 'primeng/table'; @@ -15,7 +14,6 @@ import {CheckboxModule} from 'primeng/checkbox'; @NgModule({ declarations: [ AdminJobsComponent, - JobsTableComponent, JobPostingFormComponent ], imports: [ diff --git a/frontend-implicaction/src/app/admin/jobs/components/jobs-table/jobs-table.component.scss b/frontend-implicaction/src/app/admin/jobs/components/jobs-table/jobs-table.component.scss deleted file mode 100644 index f3dfcba3..00000000 --- a/frontend-implicaction/src/app/admin/jobs/components/jobs-table/jobs-table.component.scss +++ /dev/null @@ -1,13 +0,0 @@ -::ng-deep { - .p-datatable .p-datatable-tbody > tr > td { - border-width: 0 !important; - } - - .p-datatable-thead { - - th { - background-color: transparent !important; - border: 0 !important; - } - } -} diff --git a/frontend-implicaction/src/app/admin/jobs/components/jobs-table/jobs-table.component.spec.ts b/frontend-implicaction/src/app/admin/jobs/components/jobs-table/jobs-table.component.spec.ts deleted file mode 100644 index 41224298..00000000 --- a/frontend-implicaction/src/app/admin/jobs/components/jobs-table/jobs-table.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {ComponentFixture, TestBed} from '@angular/core/testing'; - -import {JobsTableComponent} from './jobs-table.component'; - -describe('JobTableComponent', () => { - let component: JobsTableComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [JobsTableComponent] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(JobsTableComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -});