blob: bec8e310f1cb63f4061223c13c78fc962874285a [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {Component, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
import {FormBuilder, FormGroup, ValidatorFn, Validators} from '@angular/forms';
import {Observable} from 'rxjs/Observable';
import {TdStepComponent} from '@covalent/core';
import {Office} from '../../services/office/domain/office.model';
import {Employee} from '../../services/office/domain/employee.model';
import {BUSINESS, ContactDetail, EMAIL, MOBILE, PHONE} from '../../services/domain/contact/contact-detail.model';
import {FetchRequest} from '../../services/domain/paging/fetch-request.model';
import {Role} from '../../services/identity/domain/role.model';
import {User} from '../../services/identity/domain/user.model';
import {FimsValidators} from '../../common/validator/validators';
import {Store} from '@ngrx/store';
import * as fromRoot from '../../store';
import {SEARCH as SEARCH_OFFICE} from '../../store/office/office.actions';
import {SEARCH as SEARCH_ROLE} from '../../store/role/role.actions';
import { Staff } from '../../services/domain/center/staff';
export interface EmployeeFormData {
user: User;
employee: Employee;
}
export interface EmployeeSaveEvent {
detailForm: {
identifier: string;
firstName: string;
middleName: string;
lastName: string;
password: string;
role: string;
};
contactForm: {
email: string;
phone: string;
mobile: string;
};
officeForm: {
assignedOffice: string;
};
}
@Component({
selector: 'fims-center-form-component',
templateUrl: './form.component.html'
})
export class CenterFormComponent implements OnInit {
offices: Observable<Office[]>;
roles: Observable<Role[]>;
staffs: Staff[];
detailForm: FormGroup;
contactForm: FormGroup;
officeForm: FormGroup;
@ViewChild('detailsStep') step: TdStepComponent;
@Input('editMode') editMode: boolean;
@Input('formData') set formData(formData: EmployeeFormData) {
this.prepareDetailForm(formData.employee, formData.user);
this.prepareOfficeForm(formData.employee);
this.prepareContactForm(formData.employee.contactDetails);
}
@Output('onSave') onSave = new EventEmitter<EmployeeSaveEvent>();
@Output('onCancel') onCancel = new EventEmitter<void>();
constructor(private formBuilder: FormBuilder, private store: Store<fromRoot.State>) {}
ngOnInit(): void {
this.offices = this.store.select(fromRoot.getOfficeSearchResults)
.map(officePage => officePage.offices);
this.roles = this.store.select(fromRoot.getRoleSearchResults)
.map(rolesPage => rolesPage.roles);
this.fetchRoles();
this.step.open();
}
prepareDetailForm(employee: Employee, user: User): void {
const passwordValidators: ValidatorFn[] = [Validators.minLength(8)];
if (!this.editMode) {
passwordValidators.push(Validators.required);
}
this.detailForm = this.formBuilder.group({
identifier: [employee.identifier, [Validators.required, Validators.minLength(3), Validators.maxLength(32), FimsValidators.urlSafe]],
firstName: [employee.givenName, [Validators.required, Validators.maxLength(256)]],
middleName: [employee.middleName, Validators.maxLength(256)],
lastName: [employee.surname, [Validators.required, Validators.maxLength(256)]],
password: ['', passwordValidators],
role: [user ? user.role : '', Validators.required]
});
}
private prepareOfficeForm(employee: Employee) {
this.officeForm = this.formBuilder.group({
assignedOffice: [employee.assignedOffice]
});
}
private prepareContactForm(contactDetails: ContactDetail[]): void {
let phone = '';
let mobile = '';
let email = '';
const businessContacts: ContactDetail[] = contactDetails.filter(contactDetail => contactDetail.group === BUSINESS);
if (businessContacts.length) {
phone = this.getFirstItemByType(businessContacts, PHONE);
mobile = this.getFirstItemByType(businessContacts, MOBILE);
email = this.getFirstItemByType(businessContacts, EMAIL);
}
this.contactForm = this.formBuilder.group({
email: [email, [Validators.maxLength(256), FimsValidators.email]],
phone: [phone, Validators.maxLength(256)],
mobile: [mobile, Validators.maxLength(256)]
});
}
getFirstItemByType(contactDetails: ContactDetail[], type: string): string {
const items = contactDetails.filter(contact => contact.type === type);
return items.length ? items[0].value : '';
}
formsInvalid(): boolean {
return (!this.officeForm.pristine && this.officeForm.invalid) ||
(!this.contactForm.pristine && this.contactForm.invalid)
|| this.detailForm.invalid;
}
save(): void {
this.onSave.emit({
detailForm: this.detailForm.value,
contactForm: this.contactForm.value,
officeForm: this.officeForm.value
});
}
cancel(): void {
this.onCancel.emit();
}
searchOffice(searchTerm: string): void {
const fetchRequest: FetchRequest = {
searchTerm
};
this.store.dispatch({ type: SEARCH_OFFICE, payload: fetchRequest });
}
assignOffice(selections: string[]): void {
this.setFormValue(this.officeForm, {'assignedOffice': selections && selections.length > 0 ? selections[0] : undefined});
}
fetchRoles(): void {
this.store.dispatch({ type: SEARCH_ROLE });
}
private setFormValue(form: FormGroup, value: any) {
form.setValue(value);
form.markAsDirty();
}
}