diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 6cdeb920..f0c8b6e7 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -47,7 +47,7 @@ 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 { 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';
import { FieldDetailComponent } from 'app/pages/fields/field-detail.component';
@@ -121,7 +121,7 @@ export function createTranslateLoader(http: HttpClient) {
ProfileComponent,
FieldListComponent,
FieldDetailComponent,
- // TabsComponent,
+ TabsComponent,
NavigationComponent,
NavigationItemDirective,
HeaderComponent,
diff --git a/src/app/models/observation_report.ts b/src/app/models/observation_report.ts
index c8d80887..f1f0e966 100644
--- a/src/app/models/observation_report.ts
+++ b/src/app/models/observation_report.ts
@@ -14,5 +14,6 @@ export class ObservationReport extends JsonApiModel {
@Attribute({ converter: new DateConverter() }) 'publication-date': Date;
@HasMany() observers: Observer[];
+ @HasMany() observations: Observation[];
}
diff --git a/src/app/pages/observations/observation-detail.component.html b/src/app/pages/observations/observation-detail.component.html
index 3f5146e0..9fdcf597 100644
--- a/src/app/pages/observations/observation-detail.component.html
+++ b/src/app/pages/observations/observation-detail.component.html
@@ -85,6 +85,125 @@
{{'Edit observation' | tra
{{'observation.statusNote.Published' | translate}}
+
+
+
+
-
+
@@ -832,92 +866,7 @@
{{'Upload report' | translate}}
-
+
diff --git a/src/app/pages/observations/observation-detail.component.scss b/src/app/pages/observations/observation-detail.component.scss
index fce2c80a..90c0a73b 100644
--- a/src/app/pages/observations/observation-detail.component.scss
+++ b/src/app/pages/observations/observation-detail.component.scss
@@ -54,6 +54,8 @@
padding: 0;
border-top: 1px solid $lighter-grey;
border-bottom: 1px solid $lighter-grey;
+ max-height: 400px;
+ overflow: auto;
> li {
display: flex;
diff --git a/src/app/pages/observations/observation-detail.component.ts b/src/app/pages/observations/observation-detail.component.ts
index 9b7d4ce4..5b936744 100644
--- a/src/app/pages/observations/observation-detail.component.ts
+++ b/src/app/pages/observations/observation-detail.component.ts
@@ -1,6 +1,7 @@
import { TranslateService } from '@ngx-translate/core';
-import * as cloneDeep from 'lodash/cloneDeep';
-import * as orderBy from 'lodash/orderBy';
+import cloneDeep from 'lodash/cloneDeep';
+import orderBy from 'lodash/orderBy';
+import uniqBy from 'lodash/uniqBy';
import * as EXIF from 'exif-js';
import proj4 from 'proj4';
import { Law } from 'app/models/law.model';
@@ -75,13 +76,27 @@ export class ObservationDetailComponent implements OnDestroy {
documents: ObservationDocument[] = []; // Sorted by name initially
documentsToDelete: ObservationDocument[] = []; // Existing document to delete
documentsToUpload: ObservationDocument[] = []; // New document to upload
+ reportDocuments: ObservationDocument[] = []; // Documents of the selected report
evidence: ObservationDocument = this.datastoreService.createRecord(ObservationDocument, {});
+ evidenceCategories = [
+ 'No evidence', 'Upload new or select existing', 'Evidence presented in the report'
+ ];
+ evidenceCategoryOptions: any = {}; // Object of options for evidence type selection
evidenceTypes = [ // Possible types of an evidence
'Government Documents', 'Company Documents', 'Photos',
- 'Testimony from local communities', 'Other', 'Evidence presented in the report'
+ 'Testimony from local communities', 'Other'
];
evidenceTypeOptions: any = {}; // Object of options for evidence type selection
+ evidenceTabs = [{
+ id: 'existing',
+ name: 'Select from report evidences'
+ }, {
+ id: 'new',
+ name: 'Add a new evidence'
+ }]
+ currentEvidenceTab = this.evidenceTabs[0];
+
coordinatesFormats = [
'Decimal',
'Degrees and decimal minutes',
@@ -192,6 +207,7 @@ export class ObservationDetailComponent implements OnDestroy {
_country: Country = null;
_details: string;
_evidenceType: string = null;
+ _evidenceCategory: string = null;
_evidenceOnReport: string;
_severity: Severity = null;
_subcategory: Subcategory = null;
@@ -563,6 +579,17 @@ export class ObservationDetailComponent implements OnDestroy {
}
}
+ get evidenceCategory() {
+ return this.observation ? this.observation['evidence-category'] : this._evidenceCategory
+ }
+ set evidenceCategory(evidenceCategory) {
+ if (this.observation) {
+ this.observation['evidence-category'] = evidenceCategory;
+ } else {
+ this._evidenceCategory = evidenceCategory;
+ }
+ }
+
get evidenceOnReport() { return this.observation ? this.observation['evidence-on-report'] : this._evidenceOnReport }
set evidenceOnReport(evidenceOnReport) {
if (this.observation) {
@@ -648,6 +675,10 @@ export class ObservationDetailComponent implements OnDestroy {
);
}
+ get isEvidenceOnReport() {
+ return this._evidenceCategory === 'Evidence presented in the report';
+ }
+
get mapLayers(): any[] {
const layers = [];
@@ -675,6 +706,17 @@ export class ObservationDetailComponent implements OnDestroy {
get reportChoice() { return this.observation ? (this.observation['observation-report'] || null) : this._reportChoice; }
set reportChoice(reportChoice) {
+ if (reportChoice && reportChoice.id) {
+ this.observationReportsService.getById(reportChoice.id, { include: 'observations,observations.observation-documents' }).then((report) => {
+ if (report.observations && report.observations.length > 0) {
+ this.reportDocuments = orderBy(
+ uniqBy(report.observations.flatMap(o => o['observation-documents']), 'id'),
+ [(d) => d.name.toLowerCase()]
+ );
+ }
+ });
+ }
+
if (this.observation) {
this.observation['observation-report'] = reportChoice;
} else {
@@ -759,12 +801,14 @@ export class ObservationDetailComponent implements OnDestroy {
private translateService: TranslateService
) {
this.updateTranslatedOptions(this.evidenceTypes, 'evidenceType');
+ this.updateTranslatedOptions(this.evidenceCategories, 'evidenceCategory');
this.updateTranslatedOptions(this.coordinatesFormats, 'coordinatesFormat');
this.updateMultiSelectTexts();
this.translateService.onLangChange.subscribe(() => {
this.updateTranslatedOptions(this.evidenceTypes, 'evidenceType');
+ this.updateTranslatedOptions(this.evidenceCategories, 'evidenceCategory');
this.updateTranslatedOptions(this.coordinatesFormats, 'coordinatesFormat');
});
@@ -928,6 +972,11 @@ export class ObservationDetailComponent implements OnDestroy {
return type === 'Evidence presented in the report';
}
+ public onChangeEvidenceCategory(previousType: string, type: string, typeElement: HTMLSelectElement): void {
+ console.log('onChangeEvidenceCategory', previousType, type, typeElement);
+ this.evidenceCategory = type;
+ }
+
public onChangeEvidenceType(previousType: string, type: string, typeElement: HTMLSelectElement): void {
if (!this.isEvidenceTypeOnReport(type) || !this.documents.length) {
this.evidenceType = type;
@@ -1295,6 +1344,12 @@ export class ObservationDetailComponent implements OnDestroy {
this.georeferencedPhoto.isUsed = false;
}
+ onClickAddReportDocument(document: ObservationDocument) {
+ let documentIndex = this.reportDocuments.findIndex(d => d === document);
+ this.reportDocuments.splice(documentIndex, 1);
+ document.fromReportLibrary = true;
+ this.documents.push(document);
+ }
/**
* Event handler executed when the user clicks the delete button
* of an evidence
@@ -1308,9 +1363,15 @@ export class ObservationDetailComponent implements OnDestroy {
this.documents.splice(documentIndex, 1);
if (document.id) {
- // If the document is an existing one, we add it
- // to the list of documents to delete
- this.documentsToDelete.push(cloneDeep(document));
+
+ if (document.fromReportLibrary) {
+ this.reportDocuments.push(document);
+ this.reportDocuments = orderBy(this.reportDocuments, [(d) => d.name.toLowerCase()]);
+ } else {
+ // If the document is an existing one, we add it
+ // to the list of documents to delete
+ this.documentsToDelete.push(cloneDeep(document));
+ }
} else {
// We get the index of the document within this.documentsToUpload
documentIndex = this.documentsToUpload.findIndex((d) => {
@@ -1334,6 +1395,10 @@ export class ObservationDetailComponent implements OnDestroy {
this.needsRevisionState = 'explain';
}
+ onChangeEvidenceTab(tab) {
+ this.currentEvidenceTab = tab;
+ }
+
/**
* Return whether the form is disabled
* @returns {boolean}
diff --git a/src/app/shared/tabs/tabs.component.ts b/src/app/shared/tabs/tabs.component.ts
index 4ac93a65..3cfa7449 100644
--- a/src/app/shared/tabs/tabs.component.ts
+++ b/src/app/shared/tabs/tabs.component.ts
@@ -1,76 +1,76 @@
-// import { Component, Input, HostListener, Output, EventEmitter } from '@angular/core';
+import { Component, Input, HostListener, Output, EventEmitter } from '@angular/core';
-// export interface Tab {
-// id: string;
-// name: string;
-// }
+export interface Tab {
+ id: string;
+ name: string;
+}
-// @Component({
-// selector: 'otp-tabs',
-// templateUrl: './tabs.component.html',
-// styleUrls: ['./tabs.component.scss']
-// })
-// export class TabsComponent {
+@Component({
+ selector: 'otp-tabs',
+ templateUrl: './tabs.component.html',
+ styleUrls: ['./tabs.component.scss']
+})
+export class TabsComponent {
-// @Input() tabs: Tab[] = [];
-// @Input() currentTab = 0; // Index of the current Tab
-// @Output() change: EventEmitter = new EventEmitter();
+ @Input() tabs: Tab[] = [];
+ @Input() currentTab = 0; // Index of the current Tab
+ @Output() change: EventEmitter = new EventEmitter();
-// get tab () {
-// return this.tabs[this.currentTab];
-// }
+ get tab () {
+ return this.tabs[this.currentTab];
+ }
-// set tab (tab: Tab) {
-// this.currentTab = this.tabs.findIndex(function (t) {
-// return t === tab;
-// });
+ set tab (tab: Tab) {
+ this.currentTab = this.tabs.findIndex(function (t) {
+ return t === tab;
+ });
-// this.change.emit(this.tab);
-// }
+ this.change.emit(this.tab);
+ }
-// /**
-// * Event handler executed when the user clicks a tab
-// * @param {TabItem} tab clicked tab
-// */
-// onClickTab (tab: Tab): void {
-// this.tab = tab;
-// }
+ /**
+ * Event handler executed when the user clicks a tab
+ * @param {TabItem} tab clicked tab
+ */
+ onClickTab (tab: Tab): void {
+ this.tab = tab;
+ }
-// /**
-// * Event handler executed when the user presses a key while the focus
-// * is on the component
-// * @param {KeyboardEvent} e event
-// */
-// @HostListener('keydown',['$event'])
-// onKeydown (e: KeyboardEvent) {
-// switch (e.keyCode) {
-// case 37: // left arrow
-// case 38: // top arrow
-// let previousTabIndex = (this.currentTab - 1) % this.tabs.length;
-// if (previousTabIndex < 0) {
-// previousTabIndex = this.tabs.length - 1;
-// }
-// this.tab = this.getTab(previousTabIndex);
-// break;
+ /**
+ * Event handler executed when the user presses a key while the focus
+ * is on the component
+ * @param {KeyboardEvent} e event
+ */
+ @HostListener('keydown',['$event'])
+ onKeydown (e: KeyboardEvent) {
+ switch (e.keyCode) {
+ case 37: // left arrow
+ case 38: // top arrow
+ let previousTabIndex = (this.currentTab - 1) % this.tabs.length;
+ if (previousTabIndex < 0) {
+ previousTabIndex = this.tabs.length - 1;
+ }
+ this.tab = this.getTab(previousTabIndex);
+ break;
-// case 39: // right arrow
-// case 40: // down arrow
-// const nextTabIndex = (this.currentTab + 1) % this.tabs.length;
-// this.tab = this.getTab(nextTabIndex);
-// break;
+ case 39: // right arrow
+ case 40: // down arrow
+ const nextTabIndex = (this.currentTab + 1) % this.tabs.length;
+ this.tab = this.getTab(nextTabIndex);
+ break;
-// default:
-// }
-// }
+ default:
+ }
+ }
-// /**
-// * Return the tab associated to the index
-// * @private
-// * @param {number} tabIndex index of the tab
-// * @returns {Tab} tab
-// */
-// private getTab (tabIndex: number): Tab {
-// return this.tabs[tabIndex];
-// }
+ /**
+ * Return the tab associated to the index
+ * @private
+ * @param {number} tabIndex index of the tab
+ * @returns {Tab} tab
+ */
+ private getTab (tabIndex: number): Tab {
+ return this.tabs[tabIndex];
+ }
-// }
+}
diff --git a/src/styles.scss b/src/styles.scss
index f06f4dbd..f396c2db 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -36,7 +36,7 @@
// @include foundation-reveal;
// @include foundation-switch;
@include foundation-table;
-// @include foundation-tabs;
+@include foundation-tabs;
// @include foundation-thumbnail;
// @include foundation-title-bar;
// @include foundation-tooltip;