diff --git a/src/app/components/admin-navbar/admin-navbar.component.ts b/src/app/components/admin-navbar/admin-navbar.component.ts index 05423c36..2f6ece51 100644 --- a/src/app/components/admin-navbar/admin-navbar.component.ts +++ b/src/app/components/admin-navbar/admin-navbar.component.ts @@ -42,6 +42,10 @@ export class AdminNavbarComponent { { title: 'Select boxes', links: [ + { + title: 'Professions', + url: '/admin/professions' + }, { title: 'Skills', url: '/admin/skills' diff --git a/src/app/models/salaries/salary.model.ts b/src/app/models/salaries/salary.model.ts index 2e9c7736..e7590698 100644 --- a/src/app/models/salaries/salary.model.ts +++ b/src/app/models/salaries/salary.model.ts @@ -4,7 +4,7 @@ import { Currency } from "./currency"; import { UserProfession } from "./user-profession"; import { KazakhstanCity } from "./kazakhstan-city"; -export interface UserSalaryAdminDto extends UserSalary{ +export interface UserSalaryAdminDto extends UserSalary { id: string; updatedAt: Date | null; } @@ -20,5 +20,6 @@ export interface UserSalary { city: KazakhstanCity | null; skillId: number | null; workIndustryId: number | null; + professionId: number | null; createdAt: Date; } diff --git a/src/app/modules/admin/admin-routing.module.ts b/src/app/modules/admin/admin-routing.module.ts index 113eb161..067f4be4 100644 --- a/src/app/modules/admin/admin-routing.module.ts +++ b/src/app/modules/admin/admin-routing.module.ts @@ -7,8 +7,9 @@ import { UsersAdminPageComponent } from './components/users/users-admin-page/use import { SalariesAdminPageComponent } from './components/salaries/salaries-admin-page/salaries-admin-page.component'; import { SalariesAddingChartComponent } from './components/salaries/salaries-adding-chart/salaries-adding-chart.component'; import { SalariesNotInStatsAdminPageComponent } from './components/salaries/salaries-not-in-stat-admin-page/salaries-not-in-stat-admin-page.component'; -import { SkillsPaginatedTableComponent } from './components/skills/skills-paginated-table/skills-paginated-table.component'; -import { WorkIndustriesPaginatedTableComponent } from './components/work-industries/work-industries-paginated-table/work-indusrties-paginated-table.component'; +import { SkillsPaginatedTableComponent } from './components/label-entities/skills-paginated-table/skills-paginated-table.component'; +import { WorkIndustriesPaginatedTableComponent } from './components/label-entities/work-industries-paginated-table/work-indusrties-paginated-table.component'; +import { ProfessionsPaginatedTableComponent } from './components/label-entities/professions-paginated-table/professions-paginated-table.component'; const routes: Routes = [ { path: '', component: AdminStartPageComponent }, @@ -17,6 +18,7 @@ const routes: Routes = [ { path: 'background-jobs', component: BackgroundJobsComponent }, { path: 'skills', component: SkillsPaginatedTableComponent }, { path: 'work-industries', component: WorkIndustriesPaginatedTableComponent }, + { path: 'professions', component: ProfessionsPaginatedTableComponent }, { path: 'salaries', component: SalariesAdminPageComponent }, { path: 'salaries/not-in-stats', component: SalariesNotInStatsAdminPageComponent }, { path: 'salaries/salaries-adding-trend-chart', component: SalariesAddingChartComponent }, diff --git a/src/app/modules/admin/admin.module.ts b/src/app/modules/admin/admin.module.ts index a7ad07e5..16fe36c9 100644 --- a/src/app/modules/admin/admin.module.ts +++ b/src/app/modules/admin/admin.module.ts @@ -14,8 +14,9 @@ import { SalariesAdminPageComponent } from './components/salaries/salaries-admin import { SalariesAddingChartComponent } from './components/salaries/salaries-adding-chart/salaries-adding-chart.component'; import { SalariesAdminPaginatedTableComponent } from './components/salaries/salaries-admin-paginated-table/salaries-admin-paginated-table.component'; import { SalariesNotInStatsAdminPageComponent } from './components/salaries/salaries-not-in-stat-admin-page/salaries-not-in-stat-admin-page.component'; -import { SkillsPaginatedTableComponent } from './components/skills/skills-paginated-table/skills-paginated-table.component'; -import { WorkIndustriesPaginatedTableComponent } from './components/work-industries/work-industries-paginated-table/work-indusrties-paginated-table.component'; +import { SkillsPaginatedTableComponent } from './components/label-entities/skills-paginated-table/skills-paginated-table.component'; +import { WorkIndustriesPaginatedTableComponent } from './components/label-entities/work-industries-paginated-table/work-indusrties-paginated-table.component'; +import { ProfessionsPaginatedTableComponent } from './components/label-entities/professions-paginated-table/professions-paginated-table.component'; @NgModule({ declarations: [ @@ -31,6 +32,7 @@ import { WorkIndustriesPaginatedTableComponent } from './components/work-industr SalariesNotInStatsAdminPageComponent, SkillsPaginatedTableComponent, WorkIndustriesPaginatedTableComponent, + ProfessionsPaginatedTableComponent, ], imports: [ CommonModule, diff --git a/src/app/modules/admin/components/skills/skills-paginated-table/skill-edit-form.ts b/src/app/modules/admin/components/label-entities/label-entity-edit-form.ts similarity index 74% rename from src/app/modules/admin/components/skills/skills-paginated-table/skill-edit-form.ts rename to src/app/modules/admin/components/label-entities/label-entity-edit-form.ts index 9ee4c456..c0b3abe1 100644 --- a/src/app/modules/admin/components/skills/skills-paginated-table/skill-edit-form.ts +++ b/src/app/modules/admin/components/label-entities/label-entity-edit-form.ts @@ -1,10 +1,10 @@ import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { CreateSkillRequest, Skill, SkillAdmiDto, UpdateSkillRequest } from '@services/skills.service'; +import { CreateLabelEntityRequest, LabelEntityAdmiDto, UpdateLabelEntityRequest } from '@services/label-entity.model'; import { RandomHexColor } from '@shared/value-objects/random-hex-color'; -export class SkillEditForm extends FormGroup { +export class LabelEntityEditForm extends FormGroup { private readonly itemId: number | null; - constructor(item: SkillAdmiDto | null) { + constructor(item: LabelEntityAdmiDto | null) { super({ title: new FormControl(item?.title, [Validators.required, Validators.maxLength(50)]), hexColor: new FormControl(item?.hexColorAsString ?? new RandomHexColor().toString(), [ @@ -20,7 +20,7 @@ export class SkillEditForm extends FormGroup { this.get('hexColor')?.setValue(new RandomHexColor().toString()); } - createRequestOrNull(): CreateSkillRequest | null { + createRequestOrNull(): CreateLabelEntityRequest | null { if (!this.valid) { this.markAllAsTouched(); return null; @@ -32,7 +32,7 @@ export class SkillEditForm extends FormGroup { }; } - updateRequestOrNull(): UpdateSkillRequest | null { + updateRequestOrNull(): UpdateLabelEntityRequest | null { if (!this.valid) { this.markAllAsTouched(); return null; diff --git a/src/app/modules/admin/components/label-entities/professions-paginated-table/professions-paginated-table.component.html b/src/app/modules/admin/components/label-entities/professions-paginated-table/professions-paginated-table.component.html new file mode 100644 index 00000000..4b49a1ed --- /dev/null +++ b/src/app/modules/admin/components/label-entities/professions-paginated-table/professions-paginated-table.component.html @@ -0,0 +1,81 @@ +Professions + +
+
+
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + +
IDTitleColorEmail
{{ item.id }}{{ item.title }} + {{ + item.hexColorAsString + }} + {{ item.createdBy }} + + +
+
+
+
+
+ + + + +
+
+ + + +
+ +
+
+ + +
+ + +
+ +
+ +
+
+
+ + +
+ +
+
+ + +
No one has not created any profession yet
+
diff --git a/src/app/modules/admin/components/label-entities/professions-paginated-table/professions-paginated-table.component.spec.ts b/src/app/modules/admin/components/label-entities/professions-paginated-table/professions-paginated-table.component.spec.ts new file mode 100644 index 00000000..9809d038 --- /dev/null +++ b/src/app/modules/admin/components/label-entities/professions-paginated-table/professions-paginated-table.component.spec.ts @@ -0,0 +1,29 @@ +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { mostUsedImports, testUtilStubs, mostUsedServices } from '@shared/test-utils'; +import { ProfessionsPaginatedTableComponent } from './professions-paginated-table.component'; +import { ProfessionsService } from '@services/professions.service'; + +describe('ProfessionsPaginatedTableComponent', () => { + let component: ProfessionsPaginatedTableComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ProfessionsPaginatedTableComponent], + imports: [...mostUsedImports], + providers: [...testUtilStubs, ...mostUsedServices, ProfessionsService], + schemas: [CUSTOM_ELEMENTS_SCHEMA] + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ProfessionsPaginatedTableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/modules/admin/components/label-entities/professions-paginated-table/professions-paginated-table.component.ts b/src/app/modules/admin/components/label-entities/professions-paginated-table/professions-paginated-table.component.ts new file mode 100644 index 00000000..11db2fbb --- /dev/null +++ b/src/app/modules/admin/components/label-entities/professions-paginated-table/professions-paginated-table.component.ts @@ -0,0 +1,112 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { TitleService } from '@services/title.service'; +import { AlertService } from '@shared/components/alert/services/alert.service'; +import { ConfirmMsg } from '@shared/components/dialogs/models/confirm-msg'; +import { DialogMessage } from '@shared/components/dialogs/models/dialog-message'; +import { untilDestroyed } from '@shared/subscriptions/until-destroyed'; +import { LabelEntityAdmiDto } from '@services/label-entity.model'; +import { LabelEntityEditForm } from '../label-entity-edit-form'; +import { ProfessionsService } from '@services/professions.service'; + +@Component({ + templateUrl: './professions-paginated-table.component.html' +}) +export class ProfessionsPaginatedTableComponent implements OnInit, OnDestroy { + items: Array | null = null; + + confirmDeletionMessage: DialogMessage | null = null; + editForm: LabelEntityEditForm | null = null; + itemToEdit: LabelEntityAdmiDto | null = null; + + constructor( + private readonly title: TitleService, + private readonly alert: AlertService, + private readonly service: ProfessionsService + ) {} + + ngOnDestroy(): void { + this.title.resetTitle(); + } + + ngOnInit(): void { + this.title.setTitle('Professions'); + this.service + .all() + .pipe(untilDestroyed(this)) + .subscribe((data) => { + this.items = data; + }); + } + + edit(item: LabelEntityAdmiDto): void { + this.editForm = new LabelEntityEditForm(item); + this.itemToEdit = item; + } + + create(): void { + this.editForm = new LabelEntityEditForm(null); + this.itemToEdit = null; + } + + onEditFormSubmit(): void { + + if (this.editForm == null) { + return; + } + + if (this.itemToEdit != null) { + const updateRequest = this.editForm.updateRequestOrNull(); + if (updateRequest == null) { + return; + } + + this.service + .update(updateRequest) + .pipe(untilDestroyed(this)) + .subscribe(() => { + this.alert.success('The profession was updated'); + this.editForm = null; + this.ngOnInit(); + }); + + return; + } + + const createRequest = this.editForm.createRequestOrNull(); + if (createRequest == null) { + return; + } + + this.service + .create(createRequest) + .pipe(untilDestroyed(this)) + .subscribe(() => { + this.alert.success('The profession was created'); + this.editForm = null; + this.ngOnInit(); + }); + } + + onEditModalDlgClose(): void { + this.editForm = null; + } + + delete(item: LabelEntityAdmiDto): void { + this.confirmDeletionMessage = new DialogMessage( + new ConfirmMsg( + 'Delete the profession', + 'Are you sure to delete?', + () => { + this.service + .delete(item.id!) + .pipe(untilDestroyed(this)) + .subscribe(() => { + this.alert.success('The profession was removed'); + this.confirmDeletionMessage = null; + this.ngOnInit(); + }); + } + ) + ); + } +} diff --git a/src/app/modules/admin/components/skills/skills-paginated-table/skills-paginated-table.component.html b/src/app/modules/admin/components/label-entities/skills-paginated-table/skills-paginated-table.component.html similarity index 100% rename from src/app/modules/admin/components/skills/skills-paginated-table/skills-paginated-table.component.html rename to src/app/modules/admin/components/label-entities/skills-paginated-table/skills-paginated-table.component.html diff --git a/src/app/modules/admin/components/skills/skills-paginated-table/skills-paginated-table.component.spec.ts b/src/app/modules/admin/components/label-entities/skills-paginated-table/skills-paginated-table.component.spec.ts similarity index 100% rename from src/app/modules/admin/components/skills/skills-paginated-table/skills-paginated-table.component.spec.ts rename to src/app/modules/admin/components/label-entities/skills-paginated-table/skills-paginated-table.component.spec.ts diff --git a/src/app/modules/admin/components/skills/skills-paginated-table/skills-paginated-table.component.ts b/src/app/modules/admin/components/label-entities/skills-paginated-table/skills-paginated-table.component.ts similarity index 83% rename from src/app/modules/admin/components/skills/skills-paginated-table/skills-paginated-table.component.ts rename to src/app/modules/admin/components/label-entities/skills-paginated-table/skills-paginated-table.component.ts index a38b50b9..06f4d85e 100644 --- a/src/app/modules/admin/components/skills/skills-paginated-table/skills-paginated-table.component.ts +++ b/src/app/modules/admin/components/label-entities/skills-paginated-table/skills-paginated-table.component.ts @@ -1,22 +1,22 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Label } from '@models/user-label.model'; import { TitleService } from '@services/title.service'; import { AlertService } from '@shared/components/alert/services/alert.service'; import { ConfirmMsg } from '@shared/components/dialogs/models/confirm-msg'; import { DialogMessage } from '@shared/components/dialogs/models/dialog-message'; import { untilDestroyed } from '@shared/subscriptions/until-destroyed'; -import { SkillEditForm } from './skill-edit-form'; -import { SkillAdmiDto, SkillsService } from '@services/skills.service'; +import { SkillsService } from '@services/skills.service'; +import { LabelEntityAdmiDto } from '@services/label-entity.model'; +import { LabelEntityEditForm } from '../label-entity-edit-form'; @Component({ templateUrl: './skills-paginated-table.component.html' }) export class SkillsPaginatedTableComponent implements OnInit, OnDestroy { - skills: Array | null = null; + skills: Array | null = null; confirmDeletionMessage: DialogMessage | null = null; - editForm: SkillEditForm | null = null; - itemToEdit: SkillAdmiDto | null = null; + editForm: LabelEntityEditForm | null = null; + itemToEdit: LabelEntityAdmiDto | null = null; constructor( private readonly title: TitleService, @@ -38,13 +38,13 @@ export class SkillsPaginatedTableComponent implements OnInit, OnDestroy { }); } - edit(item: SkillAdmiDto): void { - this.editForm = new SkillEditForm(item); + edit(item: LabelEntityAdmiDto): void { + this.editForm = new LabelEntityEditForm(item); this.itemToEdit = item; } create(): void { - this.editForm = new SkillEditForm(null); + this.editForm = new LabelEntityEditForm(null); this.itemToEdit = null; } @@ -91,7 +91,7 @@ export class SkillsPaginatedTableComponent implements OnInit, OnDestroy { this.editForm = null; } - delete(item: SkillAdmiDto): void { + delete(item: LabelEntityAdmiDto): void { this.confirmDeletionMessage = new DialogMessage( new ConfirmMsg( 'Delete the skill', diff --git a/src/app/modules/admin/components/work-industries/work-industries-paginated-table/work-indusrties-paginated-table.component.html b/src/app/modules/admin/components/label-entities/work-industries-paginated-table/work-indusrties-paginated-table.component.html similarity index 100% rename from src/app/modules/admin/components/work-industries/work-industries-paginated-table/work-indusrties-paginated-table.component.html rename to src/app/modules/admin/components/label-entities/work-industries-paginated-table/work-indusrties-paginated-table.component.html diff --git a/src/app/modules/admin/components/work-industries/work-industries-paginated-table/work-indusrties-paginated-table.component.spec.ts b/src/app/modules/admin/components/label-entities/work-industries-paginated-table/work-indusrties-paginated-table.component.spec.ts similarity index 100% rename from src/app/modules/admin/components/work-industries/work-industries-paginated-table/work-indusrties-paginated-table.component.spec.ts rename to src/app/modules/admin/components/label-entities/work-industries-paginated-table/work-indusrties-paginated-table.component.spec.ts diff --git a/src/app/modules/admin/components/work-industries/work-industries-paginated-table/work-indusrties-paginated-table.component.ts b/src/app/modules/admin/components/label-entities/work-industries-paginated-table/work-indusrties-paginated-table.component.ts similarity index 78% rename from src/app/modules/admin/components/work-industries/work-industries-paginated-table/work-indusrties-paginated-table.component.ts rename to src/app/modules/admin/components/label-entities/work-industries-paginated-table/work-indusrties-paginated-table.component.ts index 3ca74649..2ec27ae3 100644 --- a/src/app/modules/admin/components/work-industries/work-industries-paginated-table/work-indusrties-paginated-table.component.ts +++ b/src/app/modules/admin/components/label-entities/work-industries-paginated-table/work-indusrties-paginated-table.component.ts @@ -4,23 +4,24 @@ import { AlertService } from '@shared/components/alert/services/alert.service'; import { ConfirmMsg } from '@shared/components/dialogs/models/confirm-msg'; import { DialogMessage } from '@shared/components/dialogs/models/dialog-message'; import { untilDestroyed } from '@shared/subscriptions/until-destroyed'; -import { WorkIndusrtiesService, WorkIndustryAdmiDto } from '@services/work-industry.service'; -import { WorkIndustryEditForm } from './work-industry-edit-form'; +import { WorkIndusrtiesService } from '@services/work-industry.service'; +import { LabelEntityAdmiDto } from '@services/label-entity.model'; +import { LabelEntityEditForm } from '../label-entity-edit-form'; @Component({ templateUrl: './work-indusrties-paginated-table.component.html' }) export class WorkIndustriesPaginatedTableComponent implements OnInit, OnDestroy { - items: Array | null = null; + items: Array | null = null; confirmDeletionMessage: DialogMessage | null = null; - editForm: WorkIndustryEditForm | null = null; - itemToEdit: WorkIndustryAdmiDto | null = null; + editForm: LabelEntityEditForm | null = null; + itemToEdit: LabelEntityAdmiDto | null = null; constructor( private readonly title: TitleService, private readonly alert: AlertService, - private readonly skillService: WorkIndusrtiesService + private readonly service: WorkIndusrtiesService ) {} ngOnDestroy(): void { @@ -29,7 +30,7 @@ export class WorkIndustriesPaginatedTableComponent implements OnInit, OnDestroy ngOnInit(): void { this.title.setTitle('Industries'); - this.skillService + this.service .all() .pipe(untilDestroyed(this)) .subscribe((data) => { @@ -37,13 +38,13 @@ export class WorkIndustriesPaginatedTableComponent implements OnInit, OnDestroy }); } - edit(item: WorkIndustryAdmiDto): void { - this.editForm = new WorkIndustryEditForm(item); + edit(item: LabelEntityAdmiDto): void { + this.editForm = new LabelEntityEditForm(item); this.itemToEdit = item; } create(): void { - this.editForm = new WorkIndustryEditForm(null); + this.editForm = new LabelEntityEditForm(null); this.itemToEdit = null; } @@ -59,7 +60,7 @@ export class WorkIndustriesPaginatedTableComponent implements OnInit, OnDestroy return; } - this.skillService + this.service .update(updateRequest) .pipe(untilDestroyed(this)) .subscribe(() => { @@ -76,7 +77,7 @@ export class WorkIndustriesPaginatedTableComponent implements OnInit, OnDestroy return; } - this.skillService + this.service .create(createRequest) .pipe(untilDestroyed(this)) .subscribe(() => { @@ -90,13 +91,13 @@ export class WorkIndustriesPaginatedTableComponent implements OnInit, OnDestroy this.editForm = null; } - delete(item: WorkIndustryAdmiDto): void { + delete(item: LabelEntityAdmiDto): void { this.confirmDeletionMessage = new DialogMessage( new ConfirmMsg( 'Delete the industry', 'Are you sure to delete?', () => { - this.skillService + this.service .delete(item.id!) .pipe(untilDestroyed(this)) .subscribe(() => { diff --git a/src/app/modules/admin/components/salaries/salaries-admin-page/salaries-admin-page.component.ts b/src/app/modules/admin/components/salaries/salaries-admin-page/salaries-admin-page.component.ts index 3b8b236b..f862418e 100644 --- a/src/app/modules/admin/components/salaries/salaries-admin-page/salaries-admin-page.component.ts +++ b/src/app/modules/admin/components/salaries/salaries-admin-page/salaries-admin-page.component.ts @@ -8,6 +8,7 @@ import { untilDestroyed } from '@shared/subscriptions/until-destroyed'; import { AlertService } from '@shared/components/alert/services/alert.service'; import { SalaryAdminItem } from '../salary-admin-item'; import { SalariesTableFilter } from '../salaries-table-filter'; +import { LabelEntityDto } from '@services/label-entity.model'; @Component({ templateUrl: './salaries-admin-page.component.html' @@ -16,6 +17,10 @@ export class SalariesAdminPageComponent implements OnInit, OnDestroy { salaries: Array | null = null; source: PaginatedList | null = null; + professions: Array = []; + skills: Array = []; + industries: Array = []; + readonly filter = new SalariesTableFilter(); currentPage: number = 1; @@ -29,13 +34,23 @@ export class SalariesAdminPageComponent implements OnInit, OnDestroy { ngOnInit(): void { this.salaries = null; this.source = null; - this.loadData( - { - page: this.currentPage, - pageSize: defaultPageParams.pageSize, - ...this.filter - } - ); + + this.service + .selectBoxItems() + .pipe(untilDestroyed(this)) + .subscribe((x) => { + this.professions = x.professions; + this.skills = x.skills; + this.industries = x.industries; + + this.loadData( + { + page: this.currentPage, + pageSize: defaultPageParams.pageSize, + ...this.filter + } + ); + }); } loadData(data: AdminAllSalariesQueryParams): void { @@ -48,7 +63,7 @@ export class SalariesAdminPageComponent implements OnInit, OnDestroy { .all(data) .pipe(untilDestroyed(this)) .subscribe((x) => { - this.salaries = x.results.map((x) => new SalaryAdminItem(x)); + this.salaries = x.results.map((x) => new SalaryAdminItem(x, this.professions, this.skills, this.industries)); this.source = x; }); } diff --git a/src/app/modules/admin/components/salaries/salaries-admin-paginated-table/salaries-admin-paginated-table.component.ts b/src/app/modules/admin/components/salaries/salaries-admin-paginated-table/salaries-admin-paginated-table.component.ts index e4335dd5..cf6d4fbd 100644 --- a/src/app/modules/admin/components/salaries/salaries-admin-paginated-table/salaries-admin-paginated-table.component.ts +++ b/src/app/modules/admin/components/salaries/salaries-admin-paginated-table/salaries-admin-paginated-table.component.ts @@ -7,6 +7,7 @@ import { SalaryAdminItem } from '../salary-admin-item'; import { ConfirmMsg } from '@shared/components/dialogs/models/confirm-msg'; import { DialogMessage } from '@shared/components/dialogs/models/dialog-message'; import { SalariesTableFilter } from '../salaries-table-filter'; +import { LabelEntityDto } from '@services/label-entity.model'; @Component({ selector: 'app-salaries-admin-paginated-table', diff --git a/src/app/modules/admin/components/salaries/salaries-not-in-stat-admin-page/salaries-not-in-stat-admin-page.component.ts b/src/app/modules/admin/components/salaries/salaries-not-in-stat-admin-page/salaries-not-in-stat-admin-page.component.ts index 3d348b64..819dc843 100644 --- a/src/app/modules/admin/components/salaries/salaries-not-in-stat-admin-page/salaries-not-in-stat-admin-page.component.ts +++ b/src/app/modules/admin/components/salaries/salaries-not-in-stat-admin-page/salaries-not-in-stat-admin-page.component.ts @@ -8,6 +8,7 @@ import { untilDestroyed } from '@shared/subscriptions/until-destroyed'; import { AlertService } from '@shared/components/alert/services/alert.service'; import { SalaryAdminItem } from '../salary-admin-item'; import { SalariesTableFilter } from '../salaries-table-filter'; +import { LabelEntityDto } from '@services/label-entity.model'; @Component({ templateUrl: './salaries-not-in-stat-admin-page.component.html' @@ -16,6 +17,11 @@ export class SalariesNotInStatsAdminPageComponent implements OnInit, OnDestroy { salaries: Array | null = null; source: PaginatedList | null = null; + + professions: Array = []; + skills: Array = []; + industries: Array = []; + readonly filter = new SalariesTableFilter(); currentPage: number = 1; @@ -29,13 +35,23 @@ export class SalariesNotInStatsAdminPageComponent implements OnInit, OnDestroy { ngOnInit(): void { this.salaries = null; this.source = null; - this.loadData( - { - page: this.currentPage, - pageSize: defaultPageParams.pageSize, - ...this.filter - } - ); + + this.service + .selectBoxItems() + .pipe(untilDestroyed(this)) + .subscribe((x) => { + this.professions = x.professions; + this.skills = x.skills; + this.industries = x.industries; + + this.loadData( + { + page: this.currentPage, + pageSize: defaultPageParams.pageSize, + ...this.filter + } + ); + }); } loadData(data: AdminAllSalariesQueryParams): void { @@ -48,7 +64,7 @@ export class SalariesNotInStatsAdminPageComponent implements OnInit, OnDestroy { .salariesNotInStats(data) .pipe(untilDestroyed(this)) .subscribe((x) => { - this.salaries = x.results.map((x) => new SalaryAdminItem(x)); + this.salaries = x.results.map((x) => new SalaryAdminItem(x, this.professions, this.skills, this.industries)); this.source = x; }); } diff --git a/src/app/modules/admin/components/salaries/salary-admin-item.ts b/src/app/modules/admin/components/salaries/salary-admin-item.ts index ecf66d8d..983c31ea 100644 --- a/src/app/modules/admin/components/salaries/salary-admin-item.ts +++ b/src/app/modules/admin/components/salaries/salary-admin-item.ts @@ -4,6 +4,7 @@ import { Currency } from "@models/salaries/currency"; import { KazakhstanCity } from "@models/salaries/kazakhstan-city"; import { UserSalaryAdminDto } from "@models/salaries/salary.model"; import { UserProfession } from "@models/salaries/user-profession"; +import { LabelEntityDto } from "@services/label-entity.model"; export class SalaryAdminItem { @@ -21,7 +22,11 @@ export class SalaryAdminItem { readonly createdAt: Date; readonly updatedAt: Date; - constructor(private readonly item: UserSalaryAdminDto) { + constructor( + private readonly item: UserSalaryAdminDto, + professions: Array, + skills: Array, + industries: Array) { this.id = item.id; this.value = item.value; this.quarter = item.quarter; @@ -29,10 +34,10 @@ export class SalaryAdminItem { this.currency = Currency[item.currency]; this.company = CompanyType[item.company]; this.grade = item.grade != null ? DeveloperGrade[item.grade] : null; - this.profession = UserProfession[item.profession]; + this.profession = professions.find(p => p.id == item.professionId)?.title || '-'; this.city = item.city != null ? KazakhstanCity[item.city] : '-'; - this.skill = item.skillId != null ? item.skillId.toString() : '-'; - this.industry = item.workIndustryId != null ? item.workIndustryId.toString() : '-'; + this.skill = item.skillId != null ? skills.find(x => x.id == item.skillId)?.title ?? '-' : '-'; + this.industry = item.workIndustryId != null ? industries.find(x => x.id == item.workIndustryId)?.title ?? '-' : '-'; this.createdAt = item.createdAt; this.updatedAt = item.updatedAt ?? item.createdAt; } diff --git a/src/app/modules/admin/components/work-industries/work-industries-paginated-table/work-industry-edit-form.ts b/src/app/modules/admin/components/work-industries/work-industries-paginated-table/work-industry-edit-form.ts deleted file mode 100644 index 502607e1..00000000 --- a/src/app/modules/admin/components/work-industries/work-industries-paginated-table/work-industry-edit-form.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { CreateWorkIndustryRequest, UpdateWorkIndustryRequest, WorkIndustryAdmiDto } from '@services/work-industry.service'; -import { RandomHexColor } from '@shared/value-objects/random-hex-color'; - -export class WorkIndustryEditForm extends FormGroup { - private readonly itemId: number | null; - constructor(item: WorkIndustryAdmiDto | null) { - super({ - title: new FormControl(item?.title, [Validators.required, Validators.maxLength(50)]), - hexColor: new FormControl(item?.hexColorAsString ?? new RandomHexColor().toString(), [ - Validators.required, - Validators.maxLength(7) - ]), - }); - - this.itemId = item?.id ?? null; - } - - randomizeColor(): void { - this.get('hexColor')?.setValue(new RandomHexColor().toString()); - } - - createRequestOrNull(): CreateWorkIndustryRequest | null { - if (!this.valid) { - this.markAllAsTouched(); - return null; - } - - return { - title: this.value.title, - hexColor: this.value.hexColor, - }; - } - - updateRequestOrNull(): UpdateWorkIndustryRequest | null { - if (!this.valid) { - this.markAllAsTouched(); - return null; - } - - return { - id: this.itemId!, - title: this.value.title, - hexColor: this.value.hexColor, - }; - } -} diff --git a/src/app/modules/salaries/components/add-salary/add-salary-form.ts b/src/app/modules/salaries/components/add-salary/add-salary-form.ts index 5e563927..a935d0b1 100644 --- a/src/app/modules/salaries/components/add-salary/add-salary-form.ts +++ b/src/app/modules/salaries/components/add-salary/add-salary-form.ts @@ -80,6 +80,7 @@ static readonly digitsPattern = '^[0-9]*$'; company: Number(this.value.company) as CompanyType, grade: grade, profession: profession, + professionId: profession, city: city != KazakhstanCity.Undefined ? city : null, skillId: skillId, workIndustryId: workIndustryId, diff --git a/src/app/modules/salaries/components/add-salary/add-salary.component.ts b/src/app/modules/salaries/components/add-salary/add-salary.component.ts index 4118f6af..e7fb3854 100644 --- a/src/app/modules/salaries/components/add-salary/add-salary.component.ts +++ b/src/app/modules/salaries/components/add-salary/add-salary.component.ts @@ -9,8 +9,7 @@ import { AlertService } from '@shared/components/alert/services/alert.service'; import { UserProfession, UserProfessionEnum } from '@models/salaries/user-profession'; import { SelectItem } from '@shared/select-boxes/select-item'; import { KazakhstanCity, KazakhstanCityEnum } from '@models/salaries/kazakhstan-city'; -import { Skill } from '@services/skills.service'; -import { WorkIndustry } from '@services/work-industry.service'; +import { LabelEntityDto } from '@services/label-entity.model'; @Component({ selector: 'app-add-salary-modal', @@ -20,10 +19,10 @@ import { WorkIndustry } from '@services/work-industry.service'; export class AddSalaryComponent implements OnInit, OnDestroy { @Input() - skills: Array = []; + skills: Array = []; @Input() - industries: Array = []; + industries: Array = []; @Output() closed: EventEmitter = new EventEmitter(); diff --git a/src/app/modules/salaries/components/edit-salary/edit-salary-form.ts b/src/app/modules/salaries/components/edit-salary/edit-salary-form.ts index ab60eae6..3adec57d 100644 --- a/src/app/modules/salaries/components/edit-salary/edit-salary-form.ts +++ b/src/app/modules/salaries/components/edit-salary/edit-salary-form.ts @@ -42,6 +42,7 @@ static readonly digitsPattern = '^[0-9]*$'; return { grade: grade, profession: profession, + professionId: profession, city: city != KazakhstanCity.Undefined ? city : null, skillId: skillId, workIndustryId: workIndustryId, diff --git a/src/app/modules/salaries/components/edit-salary/edit-salary.component.ts b/src/app/modules/salaries/components/edit-salary/edit-salary.component.ts index 715da69c..729e8334 100644 --- a/src/app/modules/salaries/components/edit-salary/edit-salary.component.ts +++ b/src/app/modules/salaries/components/edit-salary/edit-salary.component.ts @@ -9,9 +9,8 @@ import { AlertService } from '@shared/components/alert/services/alert.service'; import { UserProfession, UserProfessionEnum } from '@models/salaries/user-profession'; import { SelectItem } from '@shared/select-boxes/select-item'; import { KazakhstanCity, KazakhstanCityEnum } from '@models/salaries/kazakhstan-city'; -import { Skill } from '@services/skills.service'; import { SalariesChart } from '../salaries-chart/salaries-chart'; -import { WorkIndustry } from '@services/work-industry.service'; +import { LabelEntityDto } from '@services/label-entity.model'; @Component({ selector: 'app-edit-salary-modal', @@ -21,10 +20,10 @@ import { WorkIndustry } from '@services/work-industry.service'; export class EditSalaryComponent implements OnInit, OnDestroy { @Input() - skills: Array = []; + skills: Array = []; @Input() - industries: Array = []; + industries: Array = []; @Input() salarytoBeEdited: UserSalaryAdminDto | null = null; diff --git a/src/app/modules/salaries/components/professions-distribution-chart/people-distribution-chart-object.ts b/src/app/modules/salaries/components/professions-distribution-chart/people-distribution-chart-object.ts index 2f7fa569..527d5f58 100644 --- a/src/app/modules/salaries/components/professions-distribution-chart/people-distribution-chart-object.ts +++ b/src/app/modules/salaries/components/professions-distribution-chart/people-distribution-chart-object.ts @@ -2,6 +2,7 @@ import { Chart } from 'chart.js/auto'; import { RandomRgbColor } from '../random-rgb-color'; import { UserSalary } from '@models/salaries/salary.model'; import { UserProfession, UserProfessionEnum } from '@models/salaries/user-profession'; +import { LabelEntityDto } from '@services/label-entity.model'; interface ChartDatasetType { label: string; @@ -9,6 +10,13 @@ interface ChartDatasetType { backgroundColor: Array; } +interface ProfessionItem { + professionId: number | null; + label: string; + count: number; + +} + export class PeopleDistributionChartObject extends Chart { private readonly datasets: Array = []; @@ -17,21 +25,22 @@ export class PeopleDistributionChartObject extends Chart { canvasId: string, salaries: Array, otherLimit: number, - title: string) { + title: string, + private readonly professionEntities: Array) { const datasets: Array = []; - let professions: Array<{profession: UserProfession, label: string, count: number}> = []; + let professions: Array = []; salaries.forEach(x => { - const existingItem = professions.find(p => p.profession === x.profession); + const existingItem = professions.find(p => p.professionId === x.professionId); if (existingItem != null) { existingItem.count++; return; } professions.push({ - profession: x.profession, - label: UserProfessionEnum.label(x.profession), + professionId: x.professionId, + label: professionEntities.find(p => p.id === x.professionId)?.title || '', count: 1, }); }); @@ -45,7 +54,7 @@ export class PeopleDistributionChartObject extends Chart { const dataForDataset = professionsToInclude.map(x => { return { - value: (salaries.filter(s => s.profession === x.profession).length / salaries.length) * 100, + value: (salaries.filter(s => s.professionId === x.professionId).length / salaries.length) * 100, color: new RandomRgbColor().toString(0.8), }; }); diff --git a/src/app/modules/salaries/components/professions-distribution-chart/people-distribution-chart.component.ts b/src/app/modules/salaries/components/professions-distribution-chart/people-distribution-chart.component.ts index f56ce699..1fc60911 100644 --- a/src/app/modules/salaries/components/professions-distribution-chart/people-distribution-chart.component.ts +++ b/src/app/modules/salaries/components/professions-distribution-chart/people-distribution-chart.component.ts @@ -60,7 +60,8 @@ export class PeopleDistributionChartComponent { canvasId, salaries, otherLimit, - title); + title, + this.chart!.allProfessions); var chartEl = document.getElementById(canvasId); if (chartEl != null && chartEl.parentElement != null) { diff --git a/src/app/modules/salaries/components/salaries-by-grades-chart/salaries-by-grades-chart.component.ts b/src/app/modules/salaries/components/salaries-by-grades-chart/salaries-by-grades-chart.component.ts index 2344f73e..5434f25b 100644 --- a/src/app/modules/salaries/components/salaries-by-grades-chart/salaries-by-grades-chart.component.ts +++ b/src/app/modules/salaries/components/salaries-by-grades-chart/salaries-by-grades-chart.component.ts @@ -3,6 +3,7 @@ import { UserProfession } from '@models/salaries/user-profession'; import { SalariesChartJsObject } from './salaries-chart-js-object'; import { SalariesByMoneyBarChart } from '@services/user-salaries.service'; import { SalariesPerProfession } from '../salaries-per-profession'; +import { LabelEntityDto } from '@services/label-entity.model'; @Component({ selector: 'app-salaries-by-grades-chart', @@ -20,6 +21,9 @@ export class SalariesByGradesChartComponent implements OnInit, OnDestroy { @Input() salaries: Array | null = null; + @Input() + professions: Array = []; + chartDataLocal: SalariesChartJsObject | null = null; readonly canvasId = 'canvas_' + Math.random().toString(36); diff --git a/src/app/modules/salaries/components/salaries-by-grades-chart/salaries-chart-js-object.ts b/src/app/modules/salaries/components/salaries-by-grades-chart/salaries-chart-js-object.ts index dd8f4b05..615f27c3 100644 --- a/src/app/modules/salaries/components/salaries-by-grades-chart/salaries-chart-js-object.ts +++ b/src/app/modules/salaries/components/salaries-by-grades-chart/salaries-chart-js-object.ts @@ -4,7 +4,7 @@ import { Chart, ChartType, PointStyle } from 'chart.js/auto'; import { RandomRgbColor } from '../random-rgb-color'; interface ChartDatasetType { - profession: UserProfession | null; + profession: UserProfession | null; // TODO mgorbatyuk: change to number | null label: string; data: Array; borderWidth: number; @@ -106,8 +106,8 @@ export class SalariesChartJsObject extends Chart { this.update(); } - toggleDatasetByProfession(profession: UserProfession): void { - const index = this.datasets.findIndex(x => x.profession == profession); + toggleDatasetByProfession(professionId: number | null): void { + const index = this.datasets.findIndex(x => x.profession == professionId); if (index == -1) { return; } diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html b/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html index bf68933f..a50c9dad 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html +++ b/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html @@ -159,7 +159,8 @@ + [salaries]="salariesChart.salariesPerProfessionForLocal" + [professions]="professions"> @@ -167,7 +168,8 @@ + [salaries]="salariesChart.salariesPerProfessionForRemote" + [professions]="professions"> diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.ts b/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.ts index 62c65401..75e3a29e 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.ts +++ b/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.ts @@ -14,9 +14,8 @@ import { UserProfession } from '@models/salaries/user-profession'; import { SalariesChartActivatedRoute } from './salaries-activated-route'; import { AbsoluteLink, ClipboardCopier } from '@shared/value-objects/clipboard-copier'; import { CurrentUserSalaryLabelData } from './current-user-salary-label-data'; -import { Skill, SkillsService } from '@services/skills.service'; -import { WorkIndusrtiesService, WorkIndustry } from '@services/work-industry.service'; import { MetaTagService } from '@services/meta-tag.service'; +import { LabelEntityDto } from '@services/label-entity.model'; @Component({ templateUrl: './salaries-chart.component.html', @@ -29,10 +28,11 @@ export class SalariesChartComponent implements OnInit, OnDestroy { salariesChart: SalariesChart | null = null; currentUserSalary: CurrentUserSalaryLabelData | null = null; filterData = new SalaryChartGlobalFiltersData(); - + readonly activatedRoute: SalariesChartActivatedRoute; - skills: Array = []; - industries: Array = []; + skills: Array = []; + industries: Array = []; + professions: Array = []; showDataStub = false; openAddSalaryModal = false; @@ -80,6 +80,7 @@ export class SalariesChartComponent implements OnInit, OnDestroy { .subscribe((x) => { this.skills = x.skills; this.industries = x.industries; + this.professions = x.professions; }); } @@ -95,7 +96,7 @@ export class SalariesChartComponent implements OnInit, OnDestroy { this.showDataStub = true; this.salariesChart = new StubSalariesChart(x); } else { - this.salariesChart = new SalariesChart(x); + this.salariesChart = new SalariesChart(x, this.professions); this.currentUserSalary = x.currentUserSalary != null ? new CurrentUserSalaryLabelData(x.currentUserSalary) : null; diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-chart.ts b/src/app/modules/salaries/components/salaries-chart/salaries-chart.ts index 3ba75e7a..9fe2c760 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-chart.ts +++ b/src/app/modules/salaries/components/salaries-chart/salaries-chart.ts @@ -2,6 +2,7 @@ import { formatNumber } from "@angular/common"; import { PeopleByGradesChartData, SalariesByMoneyBarChart, SalariesChartResponse } from "@services/user-salaries.service"; import { SalariesPerProfession } from "../salaries-per-profession"; import { UserSalary, UserSalaryAdminDto } from "@models/salaries/salary.model"; +import { LabelEntityDto } from "@services/label-entity.model"; export class SalariesChart { @@ -28,7 +29,7 @@ export class SalariesChart { readonly hasRemoteSalaries: boolean; - constructor(readonly data: SalariesChartResponse) { + constructor(readonly data: SalariesChartResponse, readonly allProfessions: Array) { this.averageSalary = SalariesChart.formatNumber(data.averageSalary) ?? ''; this.medianSalary = SalariesChart.formatNumber(data.medianSalary) ?? ''; @@ -41,7 +42,7 @@ export class SalariesChart { this.salariesByMoneyBarChart = data.salariesByMoneyBarChart; this.salariesByMoneyBarChartForRemote = data.salariesByMoneyBarChartForRemote; - const salariesPerProfession = SalariesPerProfession.from(data.salaries); + const salariesPerProfession = SalariesPerProfession.from(data.salaries, allProfessions); this.salariesPerProfessionForLocal = salariesPerProfession.local; this.salariesPerProfessionForRemote = salariesPerProfession.remote; diff --git a/src/app/modules/salaries/components/salaries-chart/stub-salaries-chart.ts b/src/app/modules/salaries/components/salaries-chart/stub-salaries-chart.ts index c74cc2cb..87c36d40 100644 --- a/src/app/modules/salaries/components/salaries-chart/stub-salaries-chart.ts +++ b/src/app/modules/salaries/components/salaries-chart/stub-salaries-chart.ts @@ -33,7 +33,8 @@ export class StubSalariesChart extends SalariesChart { rangeEnd: new Date(), peopleByGradesChartDataForLocal: null, peopleByGradesChartDataForRemote: null, - }); + }, + []); } private static getRandomNumber(max: number, min: number): number { diff --git a/src/app/modules/salaries/components/salaries-per-profession.ts b/src/app/modules/salaries/components/salaries-per-profession.ts index 4e1a171b..2485c881 100644 --- a/src/app/modules/salaries/components/salaries-per-profession.ts +++ b/src/app/modules/salaries/components/salaries-per-profession.ts @@ -1,24 +1,21 @@ import { CompanyType } from "@models/salaries/company-type"; import { UserSalary } from "@models/salaries/salary.model"; -import { UserProfession } from "@models/salaries/user-profession"; -import { SplittedByWhitespacesString } from "@shared/value-objects/splitted-by-whitespaces-string"; +import { LabelEntityDto } from "@services/label-entity.model"; export class SalariesPerProfession { - readonly professionName: string; turnedOn: boolean = false; constructor( - readonly profession: UserProfession, - readonly items: Array) { - this.professionName = new SplittedByWhitespacesString(UserProfession[profession]).toString(); - } + readonly profession: number | null, + readonly items: Array, + readonly professionName: string) {} toggle(): void { this.turnedOn = !this.turnedOn; } - static from(salaries: Array): { + static from(salaries: Array, professions: Array): { local: Array, remote: Array } { @@ -35,17 +32,17 @@ export class SalariesPerProfession { } } - var uniqueProfessionsForLocal = [...new Set(localSalaries.map(x => x.profession))]; - var uniqueProfessionsForRemote = [...new Set(remoteSalaries.map(x => x.profession))]; + var uniqueProfessionsForLocal = [...new Set(localSalaries.map(x => x.professionId))]; + var uniqueProfessionsForRemote = [...new Set(remoteSalaries.map(x => x.professionId))]; const local = uniqueProfessionsForLocal.map(x => { const filteredSalaries = localSalaries.filter(salary => salary.profession == x); - return new SalariesPerProfession(x, filteredSalaries); + return new SalariesPerProfession(x, filteredSalaries, professions.find(p => p.id == x)?.title || ''); }); const remote = uniqueProfessionsForRemote.map(x => { const filteredSalaries = remoteSalaries.filter(salary => salary.profession == x); - return new SalariesPerProfession(x, filteredSalaries); + return new SalariesPerProfession(x, filteredSalaries, professions.find(p => p.id == x)?.title || ''); }); return { diff --git a/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart-js-object.ts b/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart-js-object.ts index d3d2dae3..f2742a1c 100644 --- a/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart-js-object.ts +++ b/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart-js-object.ts @@ -1,17 +1,17 @@ import { Chart } from 'chart.js/auto'; import { RandomRgbColor } from '../random-rgb-color'; import { UserSalary } from '@models/salaries/salary.model'; -import { Skill } from '@services/skills.service'; +import { LabelEntityDto } from '@services/label-entity.model'; export class SalariesSkillsChartJsObject extends Chart { private readonly datasets: Array = []; - private readonly uniqueSkills: Array = []; + private readonly uniqueSkills: Array = []; constructor( canvasId: string, private readonly salaries: UserSalary[], - private readonly skills: Skill[]) { + private readonly skills: LabelEntityDto[]) { const datasets: Array = []; const uniqueSkills = SalariesSkillsChartJsObject.prepareUniqueSkills(salaries, skills); @@ -66,8 +66,8 @@ export class SalariesSkillsChartJsObject extends Chart { this.update(); } - static prepareUniqueSkills(salaries: UserSalary[], skills: Skill[]): Skill[] { - const uniqueSkills: Array = []; + static prepareUniqueSkills(salaries: UserSalary[], skills: LabelEntityDto[]): LabelEntityDto[] { + const uniqueSkills: Array = []; salaries.forEach(x => { if (x.skillId == null) { return; @@ -95,7 +95,7 @@ class ChartDatasetItem { readonly data: Array; readonly backgroundColor: Array; - constructor(uniqueSkills: Array, salaries: Array, includeNoData: boolean) { + constructor(uniqueSkills: Array, salaries: Array, includeNoData: boolean) { this.label = 'Указанные ЯП/фреймворки'; this.data = []; diff --git a/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart.component.ts b/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart.component.ts index c22ba378..ceade265 100644 --- a/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart.component.ts +++ b/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart.component.ts @@ -1,7 +1,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { UserSalary, UserSalaryAdminDto } from '@models/salaries/salary.model'; import { SalariesSkillsChartJsObject } from './salaries-skills-chart-js-object'; -import { Skill } from '@services/skills.service'; +import { LabelEntityDto } from '@services/label-entity.model'; @Component({ selector: 'app-salaries-skills-chart', @@ -11,7 +11,7 @@ import { Skill } from '@services/skills.service'; export class SalariesSkillsChartComponent { @Input() - skills: Array = []; + skills: Array = []; @Input() currentSalary: UserSalaryAdminDto | null = null; diff --git a/src/app/modules/salaries/components/work-industries-chart/work-industries-chart-js-object.ts b/src/app/modules/salaries/components/work-industries-chart/work-industries-chart-js-object.ts index cf6891e2..d6257682 100644 --- a/src/app/modules/salaries/components/work-industries-chart/work-industries-chart-js-object.ts +++ b/src/app/modules/salaries/components/work-industries-chart/work-industries-chart-js-object.ts @@ -1,17 +1,17 @@ import { Chart } from 'chart.js/auto'; import { RandomRgbColor } from '../random-rgb-color'; import { UserSalary } from '@models/salaries/salary.model'; -import { WorkIndustry } from '@services/work-industry.service'; +import { LabelEntityDto } from '@services/label-entity.model'; export class WorkIndustriesChartJsObject extends Chart { private readonly datasets: Array = []; - private readonly uniqueIndustries: Array = []; + private readonly uniqueIndustries: Array = []; constructor( canvasId: string, private readonly salaries: UserSalary[], - private readonly industries: WorkIndustry[]) { + private readonly industries: LabelEntityDto[]) { const datasets: Array = []; const uniqueIndustries = WorkIndustriesChartJsObject.prepareUniqueIndustries(salaries, industries); @@ -66,8 +66,8 @@ export class WorkIndustriesChartJsObject extends Chart { this.update(); } - static prepareUniqueIndustries(salaries: UserSalary[], industries: WorkIndustry[]): WorkIndustry[] { - const uniqueIndustries: Array = []; + static prepareUniqueIndustries(salaries: UserSalary[], industries: LabelEntityDto[]): LabelEntityDto[] { + const uniqueIndustries: Array = []; salaries.forEach(x => { if (x.workIndustryId == null) { return; @@ -95,7 +95,7 @@ class ChartDatasetItem { readonly data: Array; readonly backgroundColor: Array; - constructor(uniqueIndustries: Array, salaries: Array, includeNoData: boolean) { + constructor(uniqueIndustries: Array, salaries: Array, includeNoData: boolean) { this.label = 'Сфера работы'; this.data = []; diff --git a/src/app/modules/salaries/components/work-industries-chart/work-industries-chart.component.ts b/src/app/modules/salaries/components/work-industries-chart/work-industries-chart.component.ts index b8109810..85093f52 100644 --- a/src/app/modules/salaries/components/work-industries-chart/work-industries-chart.component.ts +++ b/src/app/modules/salaries/components/work-industries-chart/work-industries-chart.component.ts @@ -1,7 +1,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { UserSalary, UserSalaryAdminDto } from '@models/salaries/salary.model'; import { WorkIndustriesChartJsObject } from './work-industries-chart-js-object'; -import { WorkIndustry } from '@services/work-industry.service'; +import { LabelEntityDto } from '@services/label-entity.model'; @Component({ selector: 'app-work-industries-chart', @@ -11,7 +11,7 @@ import { WorkIndustry } from '@services/work-industry.service'; export class WorkIndustriesChartComponent { @Input() - industries: Array = []; + industries: Array = []; @Input() currentSalary: UserSalaryAdminDto | null = null; diff --git a/src/app/services/label-entity-base.service.ts b/src/app/services/label-entity-base.service.ts new file mode 100644 index 00000000..3c3347c2 --- /dev/null +++ b/src/app/services/label-entity-base.service.ts @@ -0,0 +1,34 @@ +import { Observable } from 'rxjs'; +import { ApiService } from './api.service'; +import { CreateLabelEntityRequest, LabelEntityAdmiDto, LabelEntityDto, UpdateLabelEntityRequest } from './label-entity.model'; + +export abstract class LabelEntityBaseService { + constructor( + private readonly root: string, + private readonly api: ApiService) {} + + all(): Observable> { + // for admis + return this.api.get(this.root + 'all'); + } + + allForSelectBoxes(): Observable> { + return this.api.get(this.root + 'for-select-boxes'); + } + + byIdSimple(id: string): Observable { + return this.api.get(this.root + id + '/simple'); + } + + create(data: CreateLabelEntityRequest): Observable { + return this.api.post(this.root, data); + } + + update(data: UpdateLabelEntityRequest): Observable { + return this.api.put(this.root, data); + } + + delete(id: number): Observable { + return this.api.delete(this.root + id); + } +} diff --git a/src/app/services/label-entity.model.ts b/src/app/services/label-entity.model.ts new file mode 100644 index 00000000..4016c79b --- /dev/null +++ b/src/app/services/label-entity.model.ts @@ -0,0 +1,19 @@ +export interface LabelEntityDto { + id: number; + title: string; + hexColorAsString: string; +} + +export interface LabelEntityAdmiDto extends LabelEntityDto { + createdById: number | null; + createdBy: string | null; +} + +export interface CreateLabelEntityRequest { + title: string; + hexColor: string; +} + +export interface UpdateLabelEntityRequest extends CreateLabelEntityRequest { + id: number; +} diff --git a/src/app/services/professions.service.ts b/src/app/services/professions.service.ts new file mode 100644 index 00000000..e9c35bf6 --- /dev/null +++ b/src/app/services/professions.service.ts @@ -0,0 +1,12 @@ +import { Injectable } from '@angular/core'; +import { ApiService } from './api.service'; +import { LabelEntityBaseService } from './label-entity-base.service'; + +@Injectable({ + providedIn: 'root' +}) +export class ProfessionsService extends LabelEntityBaseService { + constructor(api: ApiService) { + super('/api/professions/', api); + } +} diff --git a/src/app/services/skills.service.ts b/src/app/services/skills.service.ts index dbc816fb..3e53470e 100644 --- a/src/app/services/skills.service.ts +++ b/src/app/services/skills.service.ts @@ -1,52 +1,12 @@ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; import { ApiService } from './api.service'; - -export interface Skill { - id: number; - title: string; - hexColorAsString: string; -} - -export interface SkillAdmiDto extends Skill { - createdById: number | null; - createdBy: string | null; -} - -export interface CreateSkillRequest { - title: string; - hexColor: string; -} - -export interface UpdateSkillRequest extends CreateSkillRequest { - id: number; -} +import { LabelEntityBaseService } from './label-entity-base.service'; @Injectable({ providedIn: 'root' }) -export class SkillsService { - private readonly root = '/api/skills/'; - constructor(private readonly api: ApiService) {} - - all(): Observable> { - // for admis - return this.api.get(this.root + 'all'); - } - - allForSelectBoxes(): Observable> { - return this.api.get(this.root + 'for-select-boxes'); - } - - create(data: CreateSkillRequest): Observable { - return this.api.post(this.root, data); - } - - update(data: UpdateSkillRequest): Observable { - return this.api.put(this.root, data); - } - - delete(id: number): Observable { - return this.api.delete(this.root + id); +export class SkillsService extends LabelEntityBaseService { + constructor(api: ApiService) { + super('/api/skills/', api); } } diff --git a/src/app/services/user-salaries.service.ts b/src/app/services/user-salaries.service.ts index 9331d2c8..9283289e 100644 --- a/src/app/services/user-salaries.service.ts +++ b/src/app/services/user-salaries.service.ts @@ -6,13 +6,11 @@ import { CompanyType } from '@models/salaries/company-type'; import { Currency } from '@models/salaries/currency'; import { UserSalary, UserSalaryAdminDto } from '@models/salaries/salary.model'; import { UserProfession } from '@models/salaries/user-profession'; -import { PageParams, defaultPageParams } from '@models/page-params'; +import { PageParams } from '@models/page-params'; import { PaginatedList } from '@models/paginated-list'; import { ConvertObjectToHttpParams } from '@shared/value-objects/convert-object-to-http'; import { KazakhstanCity } from '@models/salaries/kazakhstan-city'; -import { NumberExtended } from '@shared/value-objects'; -import { Skill } from './skills.service'; -import { WorkIndustry } from './work-industry.service'; +import { LabelEntityDto } from './label-entity.model'; export interface CreateUserSalaryRequest extends EditUserSalaryRequest { value: number; @@ -27,6 +25,7 @@ export interface EditUserSalaryRequest { city: KazakhstanCity | null; skillId: number | null; workIndustryId: number | null; + professionId: number | null; company: CompanyType; } @@ -123,12 +122,14 @@ export class UserSalariesService { } selectBoxItems(): Observable<{ - skills: Skill[], - industries: WorkIndustry[] + skills: LabelEntityDto[], + industries: LabelEntityDto[], + professions: LabelEntityDto[] }> { return this.api.get<{ - skills: Skill[], - industries: WorkIndustry[] + skills: LabelEntityDto[], + industries: LabelEntityDto[], + professions: LabelEntityDto[] }>(this.root + 'select-box-items'); } diff --git a/src/app/services/work-industry.service.ts b/src/app/services/work-industry.service.ts index cbb82423..64c76b4c 100644 --- a/src/app/services/work-industry.service.ts +++ b/src/app/services/work-industry.service.ts @@ -1,56 +1,13 @@ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; import { ApiService } from './api.service'; - -export interface WorkIndustry { - id: number; - title: string; - hexColorAsString: string; -} - -export interface WorkIndustryAdmiDto extends WorkIndustry { - createdById: number | null; - createdBy: string | null; -} - -export interface CreateWorkIndustryRequest { - title: string; - hexColor: string; -} - -export interface UpdateWorkIndustryRequest extends CreateWorkIndustryRequest { - id: number; -} +import { LabelEntityBaseService } from './label-entity-base.service'; @Injectable({ providedIn: 'root' }) -export class WorkIndusrtiesService { - private readonly root = '/api/work-industries/'; - constructor(private readonly api: ApiService) {} - - all(): Observable> { - // for admis - return this.api.get(this.root + 'all'); - } - - allForSelectBoxes(): Observable> { - return this.api.get(this.root + 'for-select-boxes'); - } - - byIdSimple(id: string): Observable { - return this.api.get(this.root + id + '/simple'); - } - - create(data: CreateWorkIndustryRequest): Observable { - return this.api.post(this.root, data); - } - - update(data: UpdateWorkIndustryRequest): Observable { - return this.api.put(this.root, data); - } +export class WorkIndusrtiesService extends LabelEntityBaseService { - delete(id: number): Observable { - return this.api.delete(this.root + id); + constructor(api: ApiService) { + super('/api/work-industries/', api); } }