Skip to content

Commit

Permalink
list works with entities
Browse files Browse the repository at this point in the history
performance improvemenent for sort-by and page-size mat-selects, and added Maxime's fixes to use the real entities for the entities in the list (instead of the hardcoded values in the configs)
  • Loading branch information
matt-litwiller committed Jul 7, 2023
1 parent cc0b3aa commit e7d8d9a
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 57 deletions.
6 changes: 6 additions & 0 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@
<my-element></my-element> -->

<app-portal *ngIf="!hasMenu" [ngClass]="hasHeader? 'portal-hasHeader': 'portal'"></app-portal>

<!-- <app-simple-feature-list
[propertiesMap]="propertiesMap"
[entitiesList]="entitiesList"
[simpleFiltersValue]="simpleFiltersValue$ | async">
</app-simple-feature-list> -->
7 changes: 7 additions & 0 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
} from '@igo2/core';
import { AuthOptions } from '@igo2/auth';
import { PwaService } from './services/pwa.service';
import { Option } from './pages/filters/simple-filters.interface';
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
Expand All @@ -20,6 +22,11 @@ export class AppComponent {
// console.log("isMobile: ", this.isMobile);
}

// public propertiesMap: Map<string, Array<Option>> = new Map(); //string of all properties (keys) and all values associated with this property
// public entitiesAll: Array<Object>; //all entities
// public entitiesList: Array<Object> //filtered entities
// public simpleFiltersValue$: BehaviorSubject<object> = new BehaviorSubject(undefined);

public isMobile: boolean = window.innerWidth >= 768 ? false : true; //boolean to determine screen width for layout
public authConfig: AuthOptions;
private themeClass = 'qcca-theme';
Expand Down
17 changes: 17 additions & 0 deletions src/app/pages/filters/filterServices/filters-types.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
providedIn: 'root'
})
export class FiltersTypesService {

private eventSubject = new Subject<string[]>();

emitEvent(types: string[]) {
this.eventSubject.next(types);
}

onEvent() {
return this.eventSubject.asObservable();
}}
41 changes: 34 additions & 7 deletions src/app/pages/filters/simple-filters.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { FiltersAdditionalTypesService } from './filterServices/filters-addition
import { FiltersActiveFiltersService } from './filterServices/filters-active-filters.service';
import { FiltersSharedMethodsService } from './filterServices/filters-shared-methods.service';
import { FiltersAdditionalPropertiesService } from './filterServices/filters-additional-properties.service';
import { FeatureCollection } from 'geojson';
import { Feature, FeatureCollection } from 'geojson';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Component, OnInit, OnDestroy, Output, EventEmitter, ViewChild, Input, ChangeDetectorRef } from '@angular/core';
import { SimpleFilter, TypeOptions, Option } from './simple-filters.interface';
Expand All @@ -13,6 +13,7 @@ import { MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/m
import { Subscription } from 'rxjs';
import { FiltersOptionService } from './filterServices/filters-option-service.service';
import { ListEntitiesService } from '../list/listServices/list-entities-services.service';
import { FiltersTypesService } from './filterServices/filters-types.service';

@Component({
selector: 'app-simple-filters',
Expand All @@ -21,7 +22,8 @@ import { ListEntitiesService } from '../list/listServices/list-entities-services
})
export class SimpleFiltersComponent implements OnInit, OnDestroy {
@Input() isMobile: boolean;
@Input() propertiesMap: Map<string, Array<Option>>;
// @Input() propertiesMap: Map<string, Array<Option>>;
@Input() entityStore;
@Output() filterSelection: EventEmitter<object> = new EventEmitter();
@Output() activeFiltersUpdate: EventEmitter<Map<string, Option[]>> = new EventEmitter();
@ViewChild(MatAutocompleteTrigger) panelTrigger: MatAutocompleteTrigger;
Expand All @@ -43,11 +45,11 @@ export class SimpleFiltersComponent implements OnInit, OnDestroy {
public additionalTypes: Array<string> = []; //list of all additional filter types (corresponding to the keys of the map in additional properties)
public additionalProperties: Map<number, Map<string, string>> = new Map(); //map of all additional properties by entity id e.g. {80029: {municipalite: Trois-Rivières}, {mrc: ...}}
public properties: Array<string>; //string value of all properties that exist in the entities (e.g. "id", "nom", etc.)
// public propertiesMap: Map<string, Array<Option>> = new Map(); //string of all properties (keys) and all values associated with this property
public propertiesMap: Map<string, Array<Option>> = new Map(); //string of all properties (keys) and all values associated with this property
public filterTypes: Array<string> = [];

constructor(private filterTypesService: FiltersTypesService, private additionalTypesService: FiltersAdditionalTypesService, private cdRef: ChangeDetectorRef, private activeFilterService: FiltersActiveFiltersService, private listEntitiesService: ListEntitiesService, private filterMethods: FiltersSharedMethodsService, private additionalPropertiesService: FiltersAdditionalPropertiesService, private configService: ConfigService, private http: HttpClient, private formBuilder: FormBuilder, private filterOptionService: FiltersOptionService) {

constructor(private additionalTypesService: FiltersAdditionalTypesService, private cdRef: ChangeDetectorRef, private activeFilterService: FiltersActiveFiltersService, private listEntitiesService: ListEntitiesService, private filterMethods: FiltersSharedMethodsService, private additionalPropertiesService: FiltersAdditionalPropertiesService, private configService: ConfigService, private http: HttpClient, private formBuilder: FormBuilder, private filterOptionService: FiltersOptionService) {
this.entitiesAll = this.configService.getConfig("temporaryEntitiesAll");
this.entitiesList = this.entitiesAll;
}

// getter of the form group controls
Expand All @@ -56,6 +58,22 @@ export class SimpleFiltersComponent implements OnInit, OnDestroy {
}

public async ngOnInit(): Promise<void> {
this.entitiesAll = this.entityStore.entities$.getValue() as Array<Feature>;
this.entitiesList = this.entityStore.entities$.getValue() as Array<Feature>;

let properties = Object.keys(this.entitiesAll[0]["properties"]);
// console.log("properties ", properties);
for(let property of properties){
let values: Array<Option> = [];
for(let entry of this.entitiesAll){
// console.log("entry ", entry, "property ", property)
// console.log(entry["properties"][property]);
let option: Option = {nom: entry["properties"][property], type: property};
!values.includes(entry["properties"][property]) ? values.push(option) : undefined;
}
this.propertiesMap.set(property, values);
}

// get the simpleFilters config input by the user in the config file
this.simpleFiltersConfig = this.configService.getConfig('useEmbeddedVersion.simpleFilters');

Expand Down Expand Up @@ -188,7 +206,11 @@ export class SimpleFiltersComponent implements OnInit, OnDestroy {
// // when options (feature collection) are returned...
// // if type is not included in terrAPI...
// } else

console.log("propertyMap ", this.propertiesMap);

if (this.propertiesMap.has(filter.type)){
this.filterTypes.push(filter.type);
// console.log("terrapi does not contain ", filter.type);
// Add the options from the entitiesAll, not from the terrAPI call
let ops: Array<Option> = [];
Expand All @@ -202,9 +224,13 @@ export class SimpleFiltersComponent implements OnInit, OnDestroy {
}
//need to also check if it is one of the location types that are accepted for the location terrapi call... can worry about this later
else if (this.terrAPITypes.includes(filter.type)){
this.filterTypes.push(filter.type);
let options: Array<Option> = [];
for(let entity of this.entitiesAll) {
let coords = entity["properties"]["coordonnees"];
console.log("entity ", entity);
let longitude = entity["geometry"]["coordinates"][0];
let latitude = entity["geometry"]["coordinates"][1];
let coords: string = longitude + "," + latitude;
await this.filterMethods.getLocationDataFromTerrAPI(filter.type, coords).then((featureCollection: FeatureCollection) => {
featureCollection.features.forEach(feature => {
// ...push type, code and name of each option
Expand Down Expand Up @@ -243,6 +269,7 @@ export class SimpleFiltersComponent implements OnInit, OnDestroy {
}
this.additionalPropertiesService.emitEvent(this.additionalProperties);
this.additionalTypesService.emitEvent(this.additionalTypes);
this.filterTypesService.emitEvent(this.filterTypes);
typeOptions = {type: filter.type, description: filter.description, options: options};
// console.log("entities do not contain ", filter.type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<p class="option-label"> {{'simpleFeatureList.header.options.sort'| translate}} </p>
<mat-form-field id="order-select" appearance="outline">
<mat-select (selectionChange)="onSortSelected($event.value, sortOptions)" disableOptionCentering [(value)]="defaultSortOption">
<mat-option *ngFor="let sortOption of sortOptions"
<mat-option *ngFor="let sortOption of possibleSortOptions"
[value]="sortOption[1]">
{{ sortOption[1] }}
</mat-option>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { TypeOptions, Option } from '../../filters/simple-filters.interface'
import { FiltersSortService } from '../../filters/filterServices/filters-sort-service.service';
import { FiltersPageService } from '../../filters/filterServices/filters-page-service.service';
import { FiltersOptionService } from '../../filters/filterServices/filters-option-service.service';
import { FiltersTypesService } from '../../filters/filterServices/filters-types.service';
import { ConfigService } from '@igo2/core';
import { LanguageService } from '@igo2/core';

Expand All @@ -25,14 +26,70 @@ export class SimpleFeatureListHeaderComponent implements OnInit, OnChanges {
public entitiesLength: number;

public defaultSortOption: string;
public defaultSortCode: string;
public defaultPageOption: number;
public possibleSortOptions: [string, string][] = [];

constructor(private filterOptionService: FiltersOptionService, private filterSortService: FiltersSortService, private filterPageService: FiltersPageService, private configService: ConfigService, private translateService: LanguageService) { }
constructor(private filterTypeService: FiltersTypesService, private filterOptionService: FiltersOptionService, private filterSortService: FiltersSortService, private filterPageService: FiltersPageService, private configService: ConfigService, private translateService: LanguageService) { }

ngOnInit() {
// console.log("sortOptions ", this.sortOptions);
this.defaultSortOption = this.sortOptions[1][1];
// console.log("defaultOption ", this.sortOptions[1]);

this.defaultSortOption = this.sortOptions[0][1];
this.defaultSortCode = this.configService.getConfig('useEmbeddedVersion.simpleFeatureList.sortBy.attributeName');

// console.log("defaultSortCode ", this.defaultSortCode);

this.filterTypeService.onEvent().subscribe( filterTypes => {
// console.log("filterTypes event ", filterTypes);
let filter: [string, string];
for(let sortOption of filterTypes) {
for(let option of this.sortOptions) {
// console.log("option[0] ", option[0], " sortOption ", sortOption);
if(option[0] === sortOption){
filter = option;
}
}
// let filter = this.sortOptions.find(filter => filter[0] === sortOption);
// console.log("filterrrr ", filter);
if(filter && !this.possibleSortOptions.includes(filter)){
this.possibleSortOptions.push(filter);
}
}

// console.log("possibleSortOptions ", this.possibleSortOptions);

if(this.defaultSortCode === undefined) {
this.defaultSortCode = this.sortOptions[0][0]
}else{
let valid = false;
for(let sort of this.possibleSortOptions){
if(sort[0] === this.defaultSortCode){
valid = true;
}
}
if(!valid) {
this.defaultSortCode = this.sortOptions[0][0];
}
}

let set = false;
for(let possibleSortOption of this.possibleSortOptions){
// console.log("possibleSortOption ", possibleSortOption);
if(possibleSortOption[0] === this.defaultSortCode){
// console.log("matched ", this.defaultSortCode);
this.defaultSortOption = possibleSortOption[1];
this.defaultSortCode = possibleSortOption[0];
this.sortBySelected.emit(this.defaultSortCode);
set = true;
}
}
// console.log("set ", set);
// console.log("defaultcode ", this.defaultSortCode);
if(!set) {
this.sortBySelected.emit(this.defaultSortCode);
}
});

let paginator = this.configService.getConfig('useEmbeddedVersion.simpleFeatureList.paginator')
// this.defaultPageOption = this.pageOptions[0];
this.defaultPageOption = paginator.pageSize !== undefined ? paginator.pageSize : this.pageOptions[0];
Expand Down
38 changes: 28 additions & 10 deletions src/app/pages/list/simple-feature-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { FiltersSharedMethodsService } from '../filters/filterServices/filters-s
import { ListEntitiesService } from './listServices/list-entities-services.service';
import { FiltersActiveFiltersService } from '../filters/filterServices/filters-active-filters.service';
import { FiltersAdditionalTypesService } from '../filters/filterServices/filters-additional-types.service';
import { FiltersTypesService } from '../filters/filterServices/filters-types.service';

@Component({
selector: 'app-simple-feature-list',
Expand All @@ -21,14 +22,15 @@ import { FiltersAdditionalTypesService } from '../filters/filterServices/filters
})

export class SimpleFeatureListComponent implements OnInit, OnChanges, OnDestroy {
// @Input() entityStore: EntityStore; // a store that contains all the entities
@Input() entityStore: EntityStore; // a store that contains all the entities
// @Input() clickedEntities: Array<Feature>; // an array that contains the entities clicked in the map
@Input() entitiesList: Array<Object>
@Input() simpleFiltersValue: object; // an object containing the value of the filters
@Output() listSelection = new EventEmitter(); // an event emitter that outputs the entity selected in the list
// @Input() activeFilters: Map<string, Option[]>;
@Input() propertiesMap: Map<string, Array<Option>> = new Map(); //string of all properties (keys) and all values associated with this property

public filterTypes: string[];
public propertiesMap: Map<string, Array<Option>> = new Map(); //string of all properties (keys) and all values associated with this property
public terrAPIBaseURL: string = "https://geoegl.msp.gouv.qc.ca/apis/terrapi/"; // base URL of the terrAPI API
public entitiesAll: Array<Object>; // an array containing all the entities in the store
public entitiesShown: Array<Object>; // an array containing the entities currently shown
Expand Down Expand Up @@ -56,10 +58,11 @@ export class SimpleFeatureListComponent implements OnInit, OnChanges, OnDestroy
public activeFilters: Map<string, Option[]> = new Map();
public additionalProperties: Map<number, Map<string,string>>;
public additionalTypes: Array<string>;
public pageOptions: Array<number> = [1,2,5,10,25]; //page size options
public sortOptions: [string, string][] = this.configService.getConfig('useEmbeddedVersion.simpleFilters') !== undefined ? this.configService.getConfig('useEmbeddedVersion.simpleFilters').map(filter => [filter.type, filter.description]) : []; //sort options of the form ['Région', 'reg'], ['Numéro de Bureau', 'id'], ...
public pageOptions: Array<number> = this.configService.getConfig('useEmbeddedVersion.simpleFeatureList.paginator.pageSizeOptions') !== undefined ? this.configService.getConfig('useEmbeddedVersion.simpleFeatureList.paginator.pageSizeOptions') : [1,2,5,10,25];
public sortOptions: [string, string][] = this.configService.getConfig('useEmbeddedVersion.simpleFilters') !== undefined ? this.configService.getConfig('useEmbeddedVersion.simpleFilters').map(filter => [filter.type, filter.description] ) : [];

constructor(private igoLanguageModule: IgoLanguageModule, private languageService: LanguageService, private additionalTypesService: FiltersAdditionalTypesService,private activeFilterService: FiltersActiveFiltersService, private listEntitiesService: ListEntitiesService, private configService: ConfigService, private filterAdditionalPropertiesService: FiltersAdditionalPropertiesService, private filterPageService: FiltersPageService, private filterSortService: FiltersSortService) {}

constructor(private filterTypeService: FiltersTypesService, private languageService: LanguageService, private additionalTypesService: FiltersAdditionalTypesService,private activeFilterService: FiltersActiveFiltersService, private listEntitiesService: ListEntitiesService, private configService: ConfigService, private filterAdditionalPropertiesService: FiltersAdditionalPropertiesService, private filterPageService: FiltersPageService, private filterSortService: FiltersSortService) {}

ngOnInit(): void {
//set additionalProperties when they get created in the filters component
Expand All @@ -68,13 +71,15 @@ export class SimpleFeatureListComponent implements OnInit, OnChanges, OnDestroy
this.additionalProperties = event; });

// get the entities from the layer/store
// this.entitiesAll = this.entityStore.entities$.getValue() as Array<Feature>;
// this.entitiesList = this.entityStore.entities$.getValue() as Array<Feature>;
this.entitiesAll = this.entityStore.entities$.getValue() as Array<Feature>;
this.entitiesList = this.entityStore.entities$.getValue() as Array<Feature>;

console.log("entitiesAll ", this.entitiesAll);

this.simpleFeatureListConfig = this.configService.getConfig('useEmbeddedVersion.simpleFeatureList');

this.entitiesAll = this.configService.getConfig('temporaryEntitiesAll') as Array<Object>;
this.entitiesList = this.configService.getConfig('temporaryEntitiesAll') as Array<Object>;
// this.entitiesAll = this.configService.getConfig('temporaryEntitiesAll') as Array<Object>;
// this.entitiesList = this.configService.getConfig('temporaryEntitiesAll') as Array<Object>;

this.listEntitiesService.emitEvent(this.entitiesList);

Expand Down Expand Up @@ -166,6 +171,19 @@ export class SimpleFeatureListComponent implements OnInit, OnChanges, OnDestroy
console.log("additionalTypes service ", types);
})

let properties = Object.keys(this.entitiesAll[0]["properties"]);
// console.log("properties ", properties);
for(let property of properties){
let values: Array<Option> = [];
for(let entry of this.entitiesAll){
// console.log("entry ", entry, "property ", property)
// console.log(entry["properties"][property]);
let option: Option = {nom: entry["properties"][property], type: property};
!values.includes(entry["properties"][property]) ? values.push(option) : undefined;
}
this.propertiesMap.set(property, values);
}

}

ngOnChanges(changes: SimpleChanges) {
Expand Down Expand Up @@ -231,7 +249,7 @@ export class SimpleFeatureListComponent implements OnInit, OnChanges, OnDestroy
}

private sortEntities(entities: Array<Object>, sortBy: string) {
let sortedEntities: Array<Object> = [];
console.log("sortEntities ", sortBy)

if(this.additionalTypes && this.additionalTypes.includes(sortBy)) {
entities.sort((a,b) => {
Expand Down
Loading

0 comments on commit e7d8d9a

Please sign in to comment.