diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 8020ee8e..6cdeb920 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -46,6 +46,7 @@ import { CategoryListComponent } from 'app/pages/fields/categories/category-list import { HeaderComponent } from 'app/shared/header/header.component'; import { NavigationComponent } from 'app/shared/navigation/navigation.component'; import { UsersService } from 'app/services/users.service'; +import { FmusService } from 'app/services/fmus.service'; // import { TabsComponent } from 'app/shared/tabs/tabs.component'; import { ObservationDetailComponent } from 'app/pages/observations/observation-detail.component'; import { FieldListComponent } from 'app/pages/fields/field-list.component'; @@ -187,6 +188,7 @@ export function createTranslateLoader(http: HttpClient) { ObservationsService, SubcategoriesService, ObserversService, + FmusService, OperatorsService, CategoriesService, ObservationReportsService, diff --git a/src/app/pages/fields/governments/government-detail.component.html b/src/app/pages/fields/governments/government-detail.component.html index d9b5240d..c54a519e 100644 --- a/src/app/pages/fields/governments/government-detail.component.html +++ b/src/app/pages/fields/governments/government-detail.component.html @@ -26,7 +26,7 @@

{{'Edit government entity' | translate}}<
- diff --git a/src/app/pages/fields/governments/government-detail.component.ts b/src/app/pages/fields/governments/government-detail.component.ts index 366aa638..249ef84f 100644 --- a/src/app/pages/fields/governments/government-detail.component.ts +++ b/src/app/pages/fields/governments/government-detail.component.ts @@ -24,7 +24,7 @@ export class GovernmentDetailComponent { @Input() useRouter: boolean = true; @Input() showActionsOnTop: boolean = true; @Input() showSuccessMessage: boolean = true; - @Input() country: Country = null; + @Input() fixedCountry: Country = null; @Input() uniqueNameErrorMessage: string = null; @Output() afterCancel: EventEmitter = new EventEmitter(); @@ -42,7 +42,7 @@ export class GovernmentDetailComponent { } ngOnInit() { - if (!this.country) { + if (!this.fixedCountry) { this.countriesService.getAll({ sort: 'name', filter: { id: this.authService.observerCountriesIds } }) .then(data => this.countries = data) .then(() => { @@ -72,9 +72,9 @@ export class GovernmentDetailComponent { this.government = this.datastoreService.createRecord(Government, {}); } - if (this.country) { - this.countries = [this.country]; - this.government.country = this.country; + if (this.fixedCountry) { + this.countries = [this.fixedCountry]; + this.government.country = this.fixedCountry; } } diff --git a/src/app/pages/fields/operators/operator-detail.component.html b/src/app/pages/fields/operators/operator-detail.component.html index a992fc52..b191f265 100644 --- a/src/app/pages/fields/operators/operator-detail.component.html +++ b/src/app/pages/fields/operators/operator-detail.component.html @@ -36,11 +36,18 @@

{{'Edit operator' | translate}}

- -
{{'Please select a country' | translate}}
+
{{'Please select a country' | translate}}
+
+ + + +
+ +
diff --git a/src/app/pages/fields/operators/operator-detail.component.ts b/src/app/pages/fields/operators/operator-detail.component.ts index d56aea5c..e1b454dc 100644 --- a/src/app/pages/fields/operators/operator-detail.component.ts +++ b/src/app/pages/fields/operators/operator-detail.component.ts @@ -9,6 +9,10 @@ import { Country } from 'app/models/country.model'; import { CountriesService } from 'app/services/countries.service'; import { Component, EventEmitter, Input, Output } from '@angular/core'; import { forkJoin , Observable } from "rxjs"; +import { Fmu } from 'app/models/fmu.model'; +import { IMultiSelectOption, IMultiSelectTexts, IMultiSelectSettings } from 'angular-2-dropdown-multiselect'; +import { FmusService } from 'app/services/fmus.service'; +import sortBy from 'lodash/sortBy'; @Component({ selector: 'otp-operator-detail', @@ -26,11 +30,20 @@ export class OperatorDetailComponent { loading = false; nameServerError: string = null; + _fmus: Fmu[] = []; + fmusOptions: IMultiSelectOption[] = []; + fmusSelection: string[] = []; + multiSelectTexts: IMultiSelectTexts = {}; + multiSelectSettings: IMultiSelectSettings = { + enableSearch: true, + dynamicTitleMaxItems: 8 + }; + @Input() useRouter: boolean = true; @Input() showActionsOnTop: boolean = true; @Input() showSuccessMessage: boolean = true; @Input() longForm: boolean = true; - @Input() country: Country = null; + @Input() fixedCountry: Country = null; @Input() uniqueNameErrorMessage: string = null; @Output() afterCancel: EventEmitter = new EventEmitter(); @@ -44,9 +57,34 @@ export class OperatorDetailComponent { return this.operator.logo; } + get fmus() { + return this._fmus; + } + set fmus(data) { + this._fmus = data; + this.fmusOptions = sortBy(data.map(c => ({ id: c.id, name: c.name })), 'name'); + } + + get country() : Country { + return this.operator.country; + } + set country(country: Country) { + if (this.operator) { + this.operator.country = country; + + // API.get('fmus', { locale: lang, 'filter[country]': countryId, 'filter[free]': true }) + if (this.canEditFmus()) { + this.fmusService.getAll({ 'filter[country]': country.id, 'filter[free]': true }).then((data) => { + this.fmus = data; + }); + } + } + } + constructor( private countriesService: CountriesService, private operatorsService: OperatorsService, + private fmusService: FmusService, private datastoreService: DatastoreService, private router: Router, private route: ActivatedRoute, @@ -54,6 +92,7 @@ export class OperatorDetailComponent { private authService: AuthService ) { this.updateTranslatedOptions(this.operatorTypes, 'operatorType'); + this.updateMultiSelectTexts(); this.translateService.onLangChange.subscribe(() => { this.updateTranslatedOptions(this.operatorTypes, 'operatorType'); @@ -61,34 +100,41 @@ export class OperatorDetailComponent { } ngOnInit() { - if (!this.country) { - this.countriesService.getAll({ sort: 'name', filter: { id: this.authService.observerCountriesIds } }) - .then((data) => this.countries = data) - .then(() => { - if (this.operator && this.operator.id) { - this.operator.country = this.countries.find(c => c.id === this.operator.country.id); - } else { - this.operator.country = this.countries[0]; - } - }) - .catch(err => console.error(err)); // TODO: visual feedback - } - // If we're editing an operator, we need to fetch the model // and do a bit more stuff if (this.useRouter && this.route.snapshot.params.id) { this.loading = true; - this.operatorsService.getById(this.route.snapshot.params.id, { include: 'country' }) - .then(operator => this.operator = operator) + this.operatorsService.getById(this.route.snapshot.params.id, { include: 'country,fmus' }) + .then(operator => { + this.operator = operator; + this.country = operator.country; + this.fmus = operator.fmus; + this.fmusSelection = operator.fmus.map(f => f.id); + }) .catch(err => console.error(err)) // TODO: visual feedback .then(() => this.loading = false); } else { this.operator = this.datastoreService.createRecord(Operator, {}); } - if (this.country) { - this.countries = [this.country]; - this.operator.country = this.country; + if (!this.fixedCountry) { + this.countriesService.getAll({ sort: 'name', filter: { id: this.authService.observerCountriesIds } }) + .then((data) => this.countries = data) + .then(() => { + if (!this.operator) return; + + let country = null; + if (this.operator.id) { + country = this.countries.find(c => c.id === this.operator.country.id); + } else { + country = this.countries[0]; + } + this.country = country; + }) + .catch(err => console.error(err)); // TODO: visual feedback + } else { + this.countries = [this.fixedCountry]; + this.country = this.fixedCountry; } } @@ -105,6 +151,9 @@ export class OperatorDetailComponent { const isEdition = !!this.operator.id; this.nameServerError = null; + if (this.canEditFmus()) { + this.operator.fmus = this.fmus.filter(f => this.fmusSelection.includes(f.id)); + } this.operator.save() .toPromise() .then(async (savedOperator) => { @@ -173,6 +222,27 @@ export class OperatorDetailComponent { } } + canEditFmus(): boolean { + return this.canEdit() && Boolean(this.operator && !this.operator.id); + } + + onChangeFmus(options: string[]) { + this.fmusSelection = options; + } + + private async updateMultiSelectTexts() { + await Promise.all([ + this.translateService.get('multiselect.checked').toPromise(), + this.translateService.get('multiselect.checkedPlural').toPromise(), + this.translateService.get('multiselect.defaultTitle').toPromise(), + this.translateService.get('multiselect.allSelected').toPromise(), + this.translateService.get('multiselect.searchPlaceholder').toPromise(), + this.translateService.get('multiselect.searchEmptyResult').toPromise(), + ]).then(([checked, checkedPlural, defaultTitle, allSelected, searchPlaceholder, searchEmptyResult]) => { + this.multiSelectTexts = { checked, checkedPlural, defaultTitle, allSelected, searchPlaceholder, searchEmptyResult }; + }); + } + private updateTranslatedOptions(phrases: string[], field: string): void { this[`${field}Options`] = {}; const observables: Observable[] = diff --git a/src/app/pages/observations/observation-detail.component.html b/src/app/pages/observations/observation-detail.component.html index d1b17c2b..3f5146e0 100644 --- a/src/app/pages/observations/observation-detail.component.html +++ b/src/app/pages/observations/observation-detail.component.html @@ -3,7 +3,7 @@ { + + public model = Fmu; + + constructor( + protected datastoreService: DatastoreService, + protected http: HttpClient + ) { + super(); + } + + /** + * Return the list of fmus + * @param {any} [params={}] Additional params for the query + * @returns {Promise} + */ + getAll(params = {}): Promise { + return this.datastoreService.findAll(Fmu, Object.assign( + {}, + { page: { size: 3000 } }, + params + )).toPromise().then((data) => data.getModels()); + } +} diff --git a/src/assets/locale/zu.json b/src/assets/locale/zu.json index 4c469cf4..2cbf6509 100644 --- a/src/assets/locale/zu.json +++ b/src/assets/locale/zu.json @@ -397,5 +397,6 @@ "Add a new government entity to the list": "Add a new government entity to the list", "Add a new producer to the list": "Add a new producer to the list", "Please select an existing report or upload a new one": "Please select an existing report or upload a new one", - "You will not be able to submit this observation to review with unknown operator selected": "You will not be able to submit this observation to review with unknown operator selected" + "You will not be able to submit this observation to review with unknown operator selected": "You will not be able to submit this observation to review with unknown operator selected", + "fmus": "FMUs" }