Commit d4e57933 authored by hasan khaddour's avatar hasan khaddour

Add Participation crud

parent d719ff0c
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="partialTimeRatio" class="form-label">نسبة التفرغ</label> <label for="partialTimeRatio" class="form-label">نسبة التفرغ</label>
<input type="number" id="partialTimeRatio" formControlName="partialTimeRatio" class="form-control" required [min]="0" /> <input type="number" id="partialTimeRatio" formControlName="partialTimeRatio" class="form-control" required />
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="role" class="form-label">صفة المساهمة</label> <label for="role" class="form-label">صفة المساهمة</label>
......
...@@ -60,7 +60,7 @@ export class AddParticipantModalComponent { ...@@ -60,7 +60,7 @@ export class AddParticipantModalComponent {
) )
); );
formatter = (x: Employee) => x != undefined ? x.email +" / "+ x.personalInfo.firstName+" " + x.personalInfo.lastName : ""; formatter = (x: Employee) => x != undefined ? x.email +" / "+ x.personalInfo?.firstName+" " + x.personalInfo?.lastName : "";
onEmployeeSelected(employee: Employee) { onEmployeeSelected(employee: Employee) {
debugger debugger
......
<!-- edit-participant-modal.component.html -->
<div class="modal fade" id="editParticipantModal" tabindex="-1" aria-labelledby="editParticipantModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editParticipantModalLabel">تعديل معلومات مشاركة </h5>
<button type="button" class=" ml-4 mr-4 btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form [formGroup]="editParticipantForm" (ngSubmit)="onSubmit()">
<div class="mb-3">
<label for="role" class="form-label">صفة المساهمة</label>
<input type="text" id="role" formControlName="role" class="form-control" required>
</div>
<div class="mb-3">
<label for="partialTimeRatio" class="form-label">نسبة التفرغ</label>
<input type="number" id="partialTimeRatio" formControlName="partialTimeRatio" class="form-control" required>
</div>
<button type="submit" class="col-4 offset-2 btn btn-primary" [disabled]="!editParticipantForm.valid">حفظ</button>
<button type="button" class="col-4 offset-2 btn btn-secondary" data-bs-dismiss="modal">إزالة</button>
</form>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { EmployeeParticipate } from '../../../../employees/models/responses/employeeParticipate';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { ProjectService } from '../../../services/project.service';
import { ChangeEmployeeParticipationRequest } from '../../../models/requests/project-requests/ChangeEmployeeParticipationRequest';
@Component({
selector: 'edit-participant-modal',
templateUrl: './edit-participant-modal.component.html',
styleUrl: './edit-participant-modal.component.css'
})
export class EditParticipantModalComponent {
@Input() participant: EmployeeParticipate;
@Output() participantEdited = new EventEmitter<void>();
editParticipantForm: FormGroup;
constructor(private fb: FormBuilder, private projectService: ProjectService) {
this.editParticipantForm = this.fb.group({
role: ['', Validators.required],
partialTimeRatio: [0, [Validators.required, Validators.min(0)]],
});
}
ngOnChanges() {
if (this.participant) {
this.editParticipantForm.patchValue(this.participant);
}
}
onSubmit() {
if (this.editParticipantForm.valid) {
let request : ChangeEmployeeParticipationRequest ={
role: this.editParticipantForm.value.role ,
partialTimeRation: this.editParticipantForm.value.partialTimeRatio,
participantId: this.participant.employee.id ,
projectId:this.participant.projectId
}
debugger;
this
.projectService
.changeParticipation(request)
.subscribe(() => {
this.participantEdited.emit();
this.closeModal();
});
}
}
closeModal() {
const modal = document.getElementById('editParticipantModal');
if (modal) {
(modal as any).modal('hide');
}
}
}
<!-- remove-participant-modal.component.html -->
<div class="modal fade" id="removeParticipantModal" tabindex="-1" aria-labelledby="removeParticipantModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="removeParticipantModalLabel">إزالة مشارك من المشروع</h5>
<button type="button" class="ml-4 mr-4 btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>هل أنت متأكد من أنك تريد إزالة السيد {{participant.employee.personalInfo | fullname}} من قائمة المشاركين في المشروع</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إلغاء</button>
<button type="button" class="btn btn-danger" (click)="onConfirmRemove()">إزالة</button>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { EmployeeParticipate } from '../../../../employees/models/responses/employeeParticipate';
import { ProjectService } from '../../../services/project.service';
import { RemoveParticipantRequest } from '../../../models/requests/project-requests/RemoveParticipant';
@Component({
selector: 'remove-participant-modal',
templateUrl: './remove-participant-modal.component.html',
styleUrl: './remove-participant-modal.component.css'
})
export class RemoveParticipantModalComponent {
@Input() participant: EmployeeParticipate;
@Output() participantRemoved = new EventEmitter<void>();
constructor(private projectService: ProjectService) {}
onConfirmRemove() {
let request :RemoveParticipantRequest= {
ParticipantId : this.participant.employeeId,
projectId:this.participant.projectId
}
this.projectService
.removeParticipant(request)
.subscribe(() => {
this.participantRemoved.emit();
});
}
}
...@@ -13,12 +13,18 @@ ...@@ -13,12 +13,18 @@
</div> <!-- ./card-text --> </div> <!-- ./card-text -->
<div class="card-footer"> <div class="card-footer">
<div class="row align-items-center justify-content-between"> <div class="row align-items-center justify-content-between">
<div class="col-auto text-center"> <div class="col text-center">
<small> <small>
<button class="btn mr-4 ml-4 btn-primary">تفاصيل </button> <button (click)="onSelected()" class="btn btn-primary">تفاصيل </button>
<button class="btn mr-4 ml-4 btn-danger">إزالة </button>
</small> </small>
</div> </div>
<div class="col text-center">
<small>
<button [routerLink]="['/projects',participant.projectId,'/history/participationChange',participant.employeeId]" class="btn btn-secondary">التبدلات</button>
</small>
</div>
</div> </div>
</div> <!-- /.card-footer --> </div> <!-- /.card-footer -->
</div> </div>
\ No newline at end of file
import { Component, Input } from '@angular/core'; import { Component, EventEmitter, Input, Output } from '@angular/core';
import { EmployeeParticipate } from '../../../employees/models/responses/employeeParticipate'; import { EmployeeParticipate } from '../../../employees/models/responses/employeeParticipate';
@Component({ @Component({
...@@ -7,6 +7,16 @@ import { EmployeeParticipate } from '../../../employees/models/responses/employe ...@@ -7,6 +7,16 @@ import { EmployeeParticipate } from '../../../employees/models/responses/employe
styleUrl: './participant-item.component.css' styleUrl: './participant-item.component.css'
}) })
export class ParticipantItemComponent { export class ParticipantItemComponent {
@Input() participant : EmployeeParticipate @Input() participant : EmployeeParticipate
@Output() selected = new EventEmitter<EmployeeParticipate>()
@Output() edit = new EventEmitter<EmployeeParticipate>()
onSelected() {
this.selected.emit(this.participant)
}
onEdit(){
this.edit.emit(this.participant);
}
} }
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<strong class="card-title my-0">{{project.projectInfo.name}} </strong> <strong class="card-title my-0">{{project.projectInfo.name}} </strong>
<p class="small">{{project.projectInfo.description}}</p> <p class="small">{{project.projectInfo.description}}</p>
<p class="small">ينفذ من قبل {{project.executer.name}}</p> <p class="small">ينفذ من قبل {{project.executer.name}}</p>
<p class="small">الطور {{project.currentState }}</p> <p class="small">الطور {{project.currentState | stateTranslate }}</p>
<p class="small text-muted mb-0"> <span class="badge badge-light text-muted"> رمز المشروع {{project.projectInfo.code}} </span>, <span class="badge badge-light text-muted"> تاريخ البدء {{project.projectInfo.startDate | date}} </span></p> <p class="small text-muted mb-0"> <span class="badge badge-light text-muted"> رمز المشروع {{project.projectInfo.code}} </span>, <span class="badge badge-light text-muted"> تاريخ البدء {{project.projectInfo.startDate | date}} </span></p>
......
<section *ngIf="participants" class="row"> <section *ngIf="participants" class="row">
<add-participant-modal <add-participant-modal
[projectId]="projectId" [projectId]="projectId"
[paticipants]="participants" [paticipants]="participants"
(participantAdded)="onParticipantAdded()" (participantAdded)="onParticipantAdded()"
> >
</add-participant-modal>
</add-participant-modal>
<div class="row justify-content-center" *ngIf="!isDetailMode">
<div class="row justify-content-center"> <div class="col-12">
<div class="col-12"> <div class="row align-items-center my-4">
<div class="row align-items-center my-4"> <div class="col">
<div class="col"> <h2 class="h4 mb-0 page-title">قائمة المشاركين بالمشروع</h2>
<h2 class="h4 mb-0 page-title"> قائمة المشاركين بالمشروع </h2>
</div>
<div class="col-auto">
<button type="button" data-bs-toggle="modal" data-bs-target="#addParticipantModal" class="btn btn-primary"><span class="fe fe-file-plus fe-12 mr-2"></span>إضافة مشارك </button>
</div> </div>
</div> <div class="col-auto">
<hr> <button
<div class="row"> type="button"
<participant-item class="col-3" *ngFor="let participant of participants" [participant]="participant"></participant-item> data-bs-toggle="modal"
</div> data-bs-target="#addParticipantModal"
<div *ngIf="participants.length==0"> class="btn btn-primary"
>
<span class="fe fe-file-plus fe-12 mr-2"></span>إضافة مشارك
</button>
</div>
</div>
<hr />
<div class="row">
<participant-item
class="col-3"
(selected)="onDetailMode(participant)"
*ngFor="let participant of participants"
[participant]="participant"
></participant-item>
</div>
<div *ngIf="participants.length == 0">
للأسف هذا المشروع لايحوي على أية مشاركين للأسف هذا المشروع لايحوي على أية مشاركين
</div>
</div> </div>
</div> </div>
</div>
</section> <edit-participant-modal
[participant]="selectedParticipant"
(participantEdited)="onParticipantUpdated()"
></edit-participant-modal>
<remove-participant-modal
[participant]="selectedParticipant"
(participantRemoved)="onParticipantRemoved()"
>
</remove-participant-modal>
<!-- <app-remove-participant-modal [participant]="selectedParticipant" (participantRemoved)="onParticipantRemoved()"></app-remove-participant-modal> -->
<div class="row" *ngIf="isDetailMode">
<div class="card shadow mb-4 col-8 offset-2">
<div class="card-header py-3">
<div class="row align-items-center">
<div class="col-auto">
<a href="profile-posts.html" class="avatar avatar-md">
<img src="./assets/images/users/4.jpg" alt="..." class="avatar-img rounded-circle">
</a>
</div>
<div class="col ml-n2">
<strong class="mb-1">المشارك {{selectedParticipant.employee.personalInfo | fullname}}</strong><span class=" ml-1"></span>
<p class="small text-muted mb-1">صفة المساهمة {{selectedParticipant.role}}</p>
</div>
<div class="col-auto">
</div>
</div>
</div>
<div class="card-body ">
<div class="row align-items-center">
<div class="col-8 ">
<div class="small mb-2 d-flex">
<span class="text-muted flex-fill">الوظيفة / الهيئة {{selectedParticipant.employee.workInfo.workJob}} / {{selectedParticipant.employee.workInfo.workType}}</span>
<span class="text-muted">نسبة التفرغ {{selectedParticipant.partialTimeRatio}}</span>
</div>
</div>
<div class="col-8 ">
<div class="small mb-2 d-flex">
</div>
<div class="col-auto">
<button type="button" class="btn m-2 btn-sm btn-primary">استعراض تاريخ تبدلاته </button>
<button type="button" data-bs-toggle="modal" data-bs-target="#editParticipantModal" class="btn m-2 btn-sm btn-secondary">تعديل معلومات المشاركة</button>
<button type="button" data-bs-toggle="modal" data-bs-target="#removeParticipantModal" class="btn m-2 btn-sm btn-danger">إزالة</button>
</div>
</div>
</div>
</div> <!-- / .card-body -->
</div>
</div>
</section>
...@@ -12,6 +12,10 @@ import { Modal } from 'bootstrap'; ...@@ -12,6 +12,10 @@ import { Modal } from 'bootstrap';
}) })
export class ParticipantsListComponent { export class ParticipantsListComponent {
participants : EmployeeParticipate[] participants : EmployeeParticipate[]
selectedParticipant: EmployeeParticipate;
isDetailMode : boolean =false
projectId = Number(this.route.snapshot.paramMap.get('id')); projectId = Number(this.route.snapshot.paramMap.get('id'));
constructor( constructor(
private projectService :ProjectService, private projectService :ProjectService,
...@@ -25,6 +29,7 @@ export class ParticipantsListComponent { ...@@ -25,6 +29,7 @@ export class ParticipantsListComponent {
ngOnInit(): void { ngOnInit(): void {
this.loadParticipations(); this.loadParticipations();
this.isDetailMode=false;
} }
onParticipantAdded(){ onParticipantAdded(){
...@@ -32,12 +37,30 @@ export class ParticipantsListComponent { ...@@ -32,12 +37,30 @@ export class ParticipantsListComponent {
this.loadParticipations(); this.loadParticipations();
} }
setSelectedParticipant(participant: EmployeeParticipate): void {
this.selectedParticipant = participant;
}
onParticipantUpdated(): void {
this.closeModal('editParticipantModal')
this.loadParticipations();
}
onParticipantRemoved(): void {
this.isDetailMode=false ;
this.loadParticipations();
}
loadParticipations(): void{ loadParticipations(): void{
this.projectService.getParticipants(this.projectId).subscribe({ this.projectService.getParticipants(this.projectId).subscribe({
next: (data)=> { next: (data)=> {
if(!this.participants){
this.toastr.success("تم تحميل المراحل بنجاح");
}
this.participants= data this.participants= data
this.toastr.success("تم تحميل المراحل بنجاح");
} }
, ,
...@@ -48,12 +71,18 @@ export class ParticipantsListComponent { ...@@ -48,12 +71,18 @@ export class ParticipantsListComponent {
}) })
} }
onDetailMode(participant: EmployeeParticipate) {
this.selectedParticipant=participant ;
this.isDetailMode=true;
}
closeModal(name :string) { closeModal(name :string) {
const modal = document.getElementById(name); const modal = document.getElementById(name);
if (modal) { if (modal) {
// Use Bootstrap 5 JavaScript API to hide modal (modal as any).modal('hide');
const bsModal = new Modal(modal);
bsModal.hide();
} }
} }
} }
...@@ -33,6 +33,8 @@ import { FinancialItemComponent } from './components/financial-item/financial-it ...@@ -33,6 +33,8 @@ import { FinancialItemComponent } from './components/financial-item/financial-it
import { ReportControllComponent } from './components/project-controll/report-controll/report-controll.component'; import { ReportControllComponent } from './components/project-controll/report-controll/report-controll.component';
import { AddParticipantModalComponent } from './components/modals/add-participant-modal/add-participant-modal.component'; import { AddParticipantModalComponent } from './components/modals/add-participant-modal/add-participant-modal.component';
import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
import { EditParticipantModalComponent } from './components/modals/edit-participant-modal/edit-participant-modal.component';
import { RemoveParticipantModalComponent } from './components/modals/remove-participant-modal/remove-participant-modal.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
...@@ -55,7 +57,9 @@ import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap'; ...@@ -55,7 +57,9 @@ import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
FinancialSpendingComponent, FinancialSpendingComponent,
FinancialItemComponent, FinancialItemComponent,
ReportControllComponent, ReportControllComponent,
AddParticipantModalComponent AddParticipantModalComponent,
EditParticipantModalComponent,
RemoveParticipantModalComponent
], ],
providers: [ providers: [
ProjectService, ProjectService,
......
...@@ -18,6 +18,7 @@ import { AddAttachmentRequest } from '../models/requests/project-requests/AddAtt ...@@ -18,6 +18,7 @@ import { AddAttachmentRequest } from '../models/requests/project-requests/AddAtt
import { Attachment } from '../models/responses/attachment'; import { Attachment } from '../models/responses/attachment';
import { CompleteProjectRequest } from '../models/requests/project-requests/completeProjectRequest'; import { CompleteProjectRequest } from '../models/requests/project-requests/completeProjectRequest';
import { ChangeEmployeeParticipationRequest } from '../models/requests/project-requests/ChangeEmployeeParticipationRequest'; import { ChangeEmployeeParticipationRequest } from '../models/requests/project-requests/ChangeEmployeeParticipationRequest';
import { ParticipationChange } from '../models/responses/participationChange';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
...@@ -39,6 +40,12 @@ export class ProjectService { ...@@ -39,6 +40,12 @@ export class ProjectService {
return this.http.get<Project[]>(this.config.getServerUrl()+ "/Projects/ByFilter"); return this.http.get<Project[]>(this.config.getServerUrl()+ "/Projects/ByFilter");
} }
public getParticipationChangeHistory(projectId :number ):Observable<ParticipationChange[]>{
return this
.http
.get<ParticipationChange[]>(this.config.getServerUrl()+'/projets/ParticipationChangeHistory/'+projectId)
}
public getAll(pageSize : number | null , pageNumber :number |null):Observable<Project[]>{ public getAll(pageSize : number | null , pageNumber :number |null):Observable<Project[]>{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment