diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 6d185b0d0a70309b424042fe072f70fdc9ce5299..ccd5e5c277dbae1ab0609946fb454a93deaf3bf6 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -17,15 +17,15 @@ import { FundingCallDetailComponent } from './views/api/funding-call-detail/fund export const routes: Routes = [ { path : 'home', component: HomeComponent}, { path: 'applications', component: ApplicationComponent}, - { path: 'applications/:id', component: ApplicationDetailComponent}, + { path: 'applications/:id1/:id2', component: ApplicationDetailComponent}, { path: 'organizations', component: OrganizationComponent}, - { path: 'organizations/:id', component: OrganizationDetailComponent}, + { path: 'organizations/:id1', component: OrganizationDetailComponent}, { path: 'facilities', component: FacilityComponent}, - { path: 'facilities/:id', component: FacilityDetailComponent}, + { path: 'facilities/:id1', component: FacilityDetailComponent}, { path: 'access_calls', component: FundingCallComponent}, - { path: 'access_calls/:id', component: FundingCallDetailComponent}, + { path: 'access_calls/:id1', component: FundingCallDetailComponent}, { path: 'users', component: UserComponent}, - { path: 'users/:id', component: UserDetailComponent}, + { path: 'users/:id1', component: UserDetailComponent}, { path: 'groups', component: GroupComponent}, - { path: 'groups/:id', component: GroupDetailComponent} + { path: 'groups/:id1', component: GroupDetailComponent} ] diff --git a/src/app/models/access_application.ts b/src/app/models/access_application.ts index a3d5c9acf41d0ccb464a9f2c6fc09a709fd11456..c10d5e6ec746b1692081f577710b05e5ba784495 100644 --- a/src/app/models/access_application.ts +++ b/src/app/models/access_application.ts @@ -22,16 +22,17 @@ export interface IAccessApplication extends Identifiable { dates_flexible: boolean; confirmed_facility_discussion: boolean; - accept_data_processing_terms: boolean; + accepted_data_processing_terms: boolean; safety_statement: File | null; funding_statement: File | null; applicant: string | null; - funding_call: string | null; + call: string | null; created: Date | null; submitted: Date | null; last_updated: Date | null; + status: string; } export class AccessApplication implements IAccessApplication { @@ -59,16 +60,17 @@ export class AccessApplication implements IAccessApplication { confirmed_facility_discussion = false; facility_email = ""; - accept_data_processing_terms = false; + accepted_data_processing_terms = false; safety_statement = null; funding_statement = null; applicant = null; - funding_call = null; + call = null; created = null; submitted = null; - last_updated = null; + last_updated = null; + status = "CREATED"; } diff --git a/src/app/views/api/application-detail/application-detail.component.html b/src/app/views/api/application-detail/application-detail.component.html index d1acd7df0cdd7ef29af7d19c50530292195a4333..21122defa98ccba43723c833ca3b445e3c95e497 100644 --- a/src/app/views/api/application-detail/application-detail.component.html +++ b/src/app/views/api/application-detail/application-detail.component.html @@ -103,7 +103,7 @@ <mat-checkbox class="example-margin" name="confirmed_discussion" [(ngModel)]="workingItem.confirmed_facility_discussion">I have discussed this application in advance with the requested facilities.</mat-checkbox> - <mat-checkbox class="example-margin" name="accept_data_processing" [(ngModel)]="workingItem.accept_data_processing_terms">I accept the call's data processing terms.</mat-checkbox> + <mat-checkbox class="example-margin" name="accept_data_processing" [(ngModel)]="workingItem.accepted_data_processing_terms">I accept the call's data processing terms.</mat-checkbox> <div> Upload the completed funding statement document. diff --git a/src/app/views/api/application-detail/application-detail.component.ts b/src/app/views/api/application-detail/application-detail.component.ts index 78478b34c78c53ba1c66f32fc930907d0d62fddf..5a1838dc0bcdf25c2d377270016dcd09b745df77 100644 --- a/src/app/views/api/application-detail/application-detail.component.ts +++ b/src/app/views/api/application-detail/application-detail.component.ts @@ -19,6 +19,8 @@ import { AccessApplication, IAccessApplication } from '../../../models/access_ap import { ITestFacility } from '../../../models/facility'; import { ApplicationService } from '../../../services/api/application.service'; import { FacilityService } from '../../../services/api/facility.service'; +import { UserService } from '../../../services/user.service'; +import { IPortalMember } from '../../../models/core'; @Component({ selector: 'app-application-detail', @@ -49,8 +51,9 @@ export class ApplicationDetailComponent extends ItemDetailComponent<IAccessAppli _route: ActivatedRoute, _location: Location, private _facilityService: FacilityService, + _userService: UserService, _restService: ApplicationService) { - super(_route, _location, _restService); + super(_route, _location, _userService, _restService); } override ngOnInit() @@ -59,6 +62,22 @@ export class ApplicationDetailComponent extends ItemDetailComponent<IAccessAppli this._facilityService.get().subscribe(facilities => this.availableFacilities = facilities); } + override onUser(user: IPortalMember) + { + if(!this.workingItem) + { + return; + } + + const call_id = this._route.snapshot.paramMap.get('id2'); + if (call_id) + { + this.workingItem.applicant = user.url; + this.workingItem.call = call_id; + this.save(); + } + } + protected override getTemplateItem(): IAccessApplication { return new AccessApplication(); diff --git a/src/app/views/api/facility-detail/facility-detail.component.ts b/src/app/views/api/facility-detail/facility-detail.component.ts index 0ae86291940c30e17c27065f1be2d028174fdf04..3a8c00952420ce52f6c881baf06816e267dbf930 100644 --- a/src/app/views/api/facility-detail/facility-detail.component.ts +++ b/src/app/views/api/facility-detail/facility-detail.component.ts @@ -20,6 +20,7 @@ import { IOrganization } from '../../../models/core'; import { LeftNavService } from '../../../services/left-nav.service'; import { OrganizationService } from '../../../services/api/organization.service'; import { FacilityService } from '../../../services/api/facility.service'; +import { UserService } from '../../../services/user.service'; @Component({ selector: 'app-facility-detail', @@ -48,9 +49,10 @@ export class FacilityDetailComponent extends ItemDetailComponent<ITestFacility> _location: Location, private _navService: LeftNavService, _restService: FacilityService, + _userService: UserService, private _organizationService: OrganizationService ) { - super(_route, _location, _restService); + super(_route, _location, _userService, _restService); } override ngOnInit() diff --git a/src/app/views/api/funding-call-detail/funding-call-detail.component.html b/src/app/views/api/funding-call-detail/funding-call-detail.component.html index 6673fda6a75c33d15eb3ae608cc19a2fa05fa836..dbecf08dfe779d3bc7e387462db1f8d116dc0c05 100644 --- a/src/app/views/api/funding-call-detail/funding-call-detail.component.html +++ b/src/app/views/api/funding-call-detail/funding-call-detail.component.html @@ -14,7 +14,7 @@ <div style="padding:5px"><span><b>Status: </b></span>{{item.status}}</div> <div style="padding:5px"><span><b>Closing Date: </b></span>{{item.closing_date}}</div> - <button mat-flat-button style="padding:5px" [routerLink]="['/applications/create']">Apply</button> + <button mat-flat-button style="padding:5px" [routerLink]="['/applications/create', item.id]">Apply</button> </div> <div *ngIf="workingItem" class="item_view"> diff --git a/src/app/views/api/funding-call-detail/funding-call-detail.component.ts b/src/app/views/api/funding-call-detail/funding-call-detail.component.ts index 26fe9a6aafb0a63333eb113cdec779d622023ada..d6a3f440443c8ae200ae7c6ed1853ae4f31e9cd7 100644 --- a/src/app/views/api/funding-call-detail/funding-call-detail.component.ts +++ b/src/app/views/api/funding-call-detail/funding-call-detail.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { NgIf } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { ActivatedRoute, RouterModule } from '@angular/router' @@ -11,8 +11,12 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatCardModule } from '@angular/material/card'; import { ItemDetailComponent } from '../../base/item-detail/item-detail.component'; +import { IPortalMember } from '../../../models/core'; import { AccessCall, IAccessCall} from '../../../models/access_call' +import { IAccessApplication } from '../../../models/access_application' import { AccessCallService } from '../../../services/api/access-call.service'; +import { ApplicationService } from '../../../services/api/application.service'; +import { UserService } from '../../../services/user.service'; import { LeftNavService } from '../../../services/left-nav.service'; @Component({ @@ -29,16 +33,36 @@ import { LeftNavService } from '../../../services/left-nav.service'; templateUrl: './funding-call-detail.component.html', styleUrl: './funding-call-detail.component.css' }) -export class FundingCallDetailComponent extends ItemDetailComponent<IAccessCall>{ - +export class FundingCallDetailComponent extends ItemDetailComponent<IAccessCall> implements OnInit{ + + user?: IPortalMember; + application: IAccessApplication | null = null; + constructor( _route: ActivatedRoute, _location: Location, private _navService: LeftNavService, + private _applicationService: ApplicationService, + _userService: UserService, _restService: AccessCallService) { - super(_route, _location, _restService); + super(_route, _location, _userService, _restService); } + override onUser(user: IPortalMember) + { + if (this.item) + { + const query = "?applicant=" + user.id + "&call=" + this.item.id; + this._applicationService.get(query).subscribe(applications => + { + if(applications.length == 1) + { + this.application = applications[0]; + } + }) + } + } + protected override getTemplateItem(): IAccessCall { return new AccessCall(); @@ -47,5 +71,16 @@ export class FundingCallDetailComponent extends ItemDetailComponent<IAccessCall> canEdit(): boolean { return this._navService.isConsortiumAdmin(); } + + hasEditableApplication(): boolean { + if (this.application) + { + if (this.application.status == "CREATED") + { + return true; + } + } + return false; + } } diff --git a/src/app/views/api/group-detail/group-detail.component.ts b/src/app/views/api/group-detail/group-detail.component.ts index 3b9ff516c75a22fc63b7209a9e1a87f82cf69a6c..1beaa59d4364698e908d81145347011e4533f206 100644 --- a/src/app/views/api/group-detail/group-detail.component.ts +++ b/src/app/views/api/group-detail/group-detail.component.ts @@ -13,6 +13,7 @@ import {MatCardModule} from '@angular/material/card'; import { ItemDetailComponent } from '../../base/item-detail/item-detail.component'; import { Group, IGroup } from '../../../models/core' import { GroupService } from '../../../services/api/group.service'; +import { UserService } from '../../../services/user.service'; @Component({ selector: 'app-group-detail', @@ -32,8 +33,9 @@ export class GroupDetailComponent extends ItemDetailComponent<IGroup>{ constructor( _route: ActivatedRoute, _location: Location, + _userService: UserService, _restService: GroupService) { - super(_route, _location, _restService); + super(_route, _location, _userService, _restService); } protected override getTemplateItem(): IGroup diff --git a/src/app/views/api/organization-detail/organization-detail.component.ts b/src/app/views/api/organization-detail/organization-detail.component.ts index d018d5a5304149892d0cfd1310d33799eeb1daa6..fac37bee5710f85f393ec7c74c45b4a2138718da 100644 --- a/src/app/views/api/organization-detail/organization-detail.component.ts +++ b/src/app/views/api/organization-detail/organization-detail.component.ts @@ -13,6 +13,7 @@ import {MatCardModule} from '@angular/material/card'; import { ItemDetailComponent } from '../../base/item-detail/item-detail.component'; import { Organization, IOrganization } from '../../../models/core' import { OrganizationService } from '../../../services/api/organization.service'; +import { UserService } from '../../../services/user.service'; @Component({ selector: 'app-organization-detail', @@ -32,8 +33,9 @@ export class OrganizationDetailComponent extends ItemDetailComponent<IOrganizati constructor( _route: ActivatedRoute, _location: Location, + _userService: UserService, _restService: OrganizationService) { - super(_route, _location, _restService); + super(_route, _location, _userService, _restService); } protected override onBeforePost(item: IOrganization): IOrganization diff --git a/src/app/views/api/user-detail/user-detail.component.ts b/src/app/views/api/user-detail/user-detail.component.ts index 9451a1a3b7b5a66d26dc02cd9b4f85fe338293b0..e1e9a5fb567dcb21f47f9739dfc1055f95b6a411 100644 --- a/src/app/views/api/user-detail/user-detail.component.ts +++ b/src/app/views/api/user-detail/user-detail.component.ts @@ -33,7 +33,7 @@ export class UserDetailComponent extends ItemDetailComponent<IPortalMember>{ _route: ActivatedRoute, _location: Location, _restService: UserService) { - super(_route, _location, _restService); + super(_route, _location, _restService, _restService); } protected override getTemplateItem(): IPortalMember diff --git a/src/app/views/base/item-detail/item-detail.component.ts b/src/app/views/base/item-detail/item-detail.component.ts index 0fc68f146e4c0dec7fa3a0fdcaefe3a8e4b6057e..5be058e9c16df336ac1d87a118962da599a546d4 100644 --- a/src/app/views/base/item-detail/item-detail.component.ts +++ b/src/app/views/base/item-detail/item-detail.component.ts @@ -3,6 +3,7 @@ import { NgIf } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { ActivatedRoute } from '@angular/router' import { Location } from '@angular/common'; +import { Subject } from 'rxjs'; import {MatIconModule} from '@angular/material/icon'; import {MatButtonModule} from '@angular/material/button'; @@ -10,8 +11,9 @@ import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; import {MatCardModule} from '@angular/material/card'; -import { Identifiable } from '../../../models/core'; +import { Identifiable, IPortalMember } from '../../../models/core'; import { RestService } from '../../../services/rest.service'; +import { UserService } from '../../../services/user.service'; @Component({ selector: 'app-item-detail', @@ -30,18 +32,32 @@ import { RestService } from '../../../services/rest.service'; export abstract class ItemDetailComponent<T extends Identifiable> implements OnInit{ item?: T; + item_change: Subject<boolean> = new Subject<boolean>; workingItem: T | null = null; createMode: boolean = false; constructor( - private _route: ActivatedRoute, + protected _route: ActivatedRoute, private _location: Location, + private _userService: UserService, private _restService: RestService<T>) {} - ngOnInit(): void { + ngOnInit(): void + { + this.item_change.subscribe(_ => this.onItemInit()); this.getItem(); } + onItemInit() + { + this._userService.loggedInUser.subscribe(user => + {if(user){this.onUser(user);}}); + } + + onUser(_: IPortalMember) + { + } + goBack(): void { if (this.createMode || !this.workingItem) { @@ -92,17 +108,19 @@ export abstract class ItemDetailComponent<T extends Identifiable> implements OnI protected abstract getTemplateItem(): T private getItem(): void { - const id_str = this._route.snapshot.paramMap.get('id'); + const id_str = this._route.snapshot.paramMap.get('id1'); if (id_str == "create") { this.workingItem = this.getTemplateItem(); this.createMode = true; + this.item_change.next(true); } else { - const id = Number(this._route.snapshot.paramMap.get('id')); + const id = Number(this._route.snapshot.paramMap.get('id1')); this._restService.getItem(id) - .subscribe(item => this.item = item); + .subscribe(item => {this.item = item; + this.item_change.next(true);}); } }