Skip to content

Commit

Permalink
Components are more modular and their display can be controled with c…
Browse files Browse the repository at this point in the history
…onfigs

Possible layouts:
filters + map + list, filters + map, map + list, map only (original version)
  • Loading branch information
matt-litwiller committed Aug 7, 2023
1 parent cdc00ac commit 6387af5
Show file tree
Hide file tree
Showing 25 changed files with 28,464 additions and 601 deletions.
27,582 changes: 27,582 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"start": "gulp watch:locale | ng serve --host 0.0.0.0 --port 4202 --proxy-config proxy.conf.json",
"start-pwa": "ng build --configuration pwa --output-path ./dist/pwa && npm run serve.pwa",
"build": "ng build --output-hashing none --configuration production",
"package":"cat dist/igo2-quebec/{runtime,polyfills,main}.js > elements/igo2-qc-element.js",
"package": "cat dist/igo2-quebec/{runtime,polyfills,main}.js > elements/igo2-qc-element.js && cp dist/igo2-quebec/styles.css elements",
"lint": "ng lint",
"lint.fix": "ng lint --fix",
"e2e": "ng e2e --port 4300",
Expand Down Expand Up @@ -52,7 +52,7 @@
"@angular/common": "^14.3.0",
"@angular/compiler": "^14.3.0",
"@angular/core": "^14.3.0",
"@angular/elements": "^16.1.3",
"@angular/elements": "^14.3.0",
"@angular/forms": "^14.3.0",
"@angular/material": "^14.2.7",
"@angular/platform-browser": "^14.3.0",
Expand Down
34 changes: 25 additions & 9 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,49 @@

<app-menu *ngIf="hasMenu"></app-menu>

<!-- <h2>Hello world</h2>
<div cdkScrollable *ngIf="!hasMenu && useEmbeddedVersion" [ngClass]="isMobile ? 'portal-mobile-embedded': 'portal-desktop-embedded'">
<div [ngClass]="isMobile ? 'filters-and-map-mobile' : showSimpleFeatureList ? 'filters-and-map-desktop' : 'filters-and-map-only-desktop'">

<my-element></my-element> -->

<div *ngIf="!hasMenu && useEmbeddedVersion" [ngClass]="isMobile ? 'portal-mobile-embedded': 'portal-desktop-embedded'">
<div class="filters-and-map">

<app-simple-filters *ngIf="showSimpleFilters && workspace"
<!-- <h1>{{showSimpleFilters + " + " + workspace}}</h1> -->
<!-- <app-simple-filters *ngIf="showSimpleFilters && workspace"
[entityStore]="workspace.entityStore"
class="simple-filters"
[isMobile]="isMobile"
[terrAPITypes]="terrAPITypes"
></app-simple-filters> -->
<app-simple-filters *ngIf="showSimpleFilters && workspace"
[entitiesAll]="entitiesAll"
[entitiesList]="entitiesList"
class="simple-filters"
[isMobile]="isMobile"
[terrAPITypes]="terrAPITypes"
[properties]="properties"
[additionalProperties]="additionalProperties"
></app-simple-filters>

<app-portal *ngIf="!hasMenu" [ngClass]="hasHeader? 'portal-hasHeader': 'portal'" (workspaceSelected)="setSelectedWorkspace($event)"
(mapQuery)="setClickedEntities($event)"
[features]="features"
[additionalProperties]="additionalProperties"
[entitiesAll]="entitiesAll"
[entitiesList]="entitiesList"
></app-portal>

</div>
<div class="list">
<app-simple-feature-list *ngIf="workspace && workspace"
<app-simple-feature-list *ngIf="workspace && showSimpleFeatureList"
[entityStore]="workspace.entityStore"
[clickedEntities]="clickedEntities"
[terrAPITypes]="terrAPITypes"
[properties]="properties"
[entitiesAll]="entitiesAll"
[entitiesList]="entitiesList"
[additionalTypes]="additionalTypes"
[additionalProperties]="additionalProperties"
(listSelection)="onListSelection($event)"
></app-simple-feature-list>
</div>
</div>
<div *ngIf="!useEmbeddedVersion">
<div *ngIf="!useEmbeddedVersion" class="no-embedded-version">
<app-portal *ngIf="!hasMenu" [ngClass]="hasHeader? 'portal-hasHeader': 'portal'"></app-portal>
</div>
60 changes: 57 additions & 3 deletions src/app/app.component.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
@import '../../node_modules/@igo2/core/style/partial/core.variables';
@import './pages/portal/portal.variables.scss';

//angular elements copy/paste
// @use '@angular/material' as mat;

// @import '../../../../node_modules/@igo2/core/style/all.theming.scss';
// @import '../../../../node_modules/@igo2/core/style/core.theming.scss';
// @import '../../../../node_modules/@igo2/core/style/foreground.scss';
// @import '../../../../node_modules/@igo2/core/style/index.theming.scss';
// @import '../../../../node_modules/@igo2/core/style/material.font.scss';
// @import '../../../../node_modules/@igo2/core/style/setup.scss';
// @import '../../../../node_modules/@igo2/core/style/theming.scss';
// @import '../../../../node_modules/@igo2/core/style/typography.scss';
// @import '../../../../node_modules/@igo2/core/style/partial/core.variables.scss';
// @import '../../../../node_modules/@igo2/core/style/partial/media.scss';

// @import '../../../../node_modules/@igo2/core/style/themes/blue.theme.scss';
// @import './portal.variables';

// .igo-panel-header {
// height: auto !important;
// }

// igo-actionbar {
// padding-top: 0px !important;
// padding-left: 0px !important;
// }

// .overlay-container {
// visibility: hidden;
// }

//end of angular elements copy/paste

:host {
font-family: Roboto, 'Helvetica Neue', sans-serif;
}
Expand Down Expand Up @@ -117,16 +149,38 @@ spinner-with-legend-dialog {

.list {
height: fit-content;
// min-width: 50%
width: 100%
}

.filters-and-map {
min-width: 400px;
.filters-and-map-only-desktop {
min-width: 100%;
display: flex;
// width: 50%;
flex-direction: column;
height: 100%;
gap: 20px;
height: fit-content;
}

.filters-and-map-desktop {
min-width: 400;
display: flex;
width: 50%;
flex-direction: column;
height: 100%;
gap: 20px;
height: fit-content;
}

.filters-and-map-mobile {
display: flex;
flex-direction: column;
height: 100%;
gap: 20px;
height: fit-content;
}

.no-embedded-version {
height: 100%;
}

182 changes: 169 additions & 13 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ 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';
import { Workspace } from '@igo2/common';
import { MatPaginator } from '@angular/material/paginator';
import { Subscription } from 'rxjs';
import { MapState, WorkspaceState } from '@igo2/integration';
import { EditionWorkspace, Feature, FeatureWorkspace, WfsWorkspace } from '@igo2/geo';
import { Feature } from '@igo2/geo';
import { HttpClient, HttpParams } from '@angular/common/http';

Check failure on line 15 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

'HttpParams' is defined but never used

Check failure on line 15 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'HttpParams' is defined but never used
import { map } from 'rxjs/operators';
import { FeatureCollection } from 'geojson';
import { Option } from './pages/filters/simple-filters.interface';
import { FiltersAdditionalPropertiesService } from './pages/filters/filterServices/filters-additional-properties.service';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
Expand All @@ -27,7 +29,10 @@ export class AppComponent {
this.isMobile = window.innerWidth >= 768 ? false : true;
}

public features: any = null; //object: {added: Feature[]}

Check failure on line 32 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Trailing spaces not allowed

Check failure on line 32 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Trailing spaces not allowed
public terrAPIBaseURL: string = "https://geoegl.msp.gouv.qc.ca/apis/terrapi/"; // base URL of the terrAPI API
public terrAPITypes: Array<string>; // an array of strings containing the types available from terrAPI
public features: any = null; //object: {added: Feature[]}
public clickedEntities: Feature[] = [];

public showSimpleFilters: boolean = false;
Expand All @@ -41,13 +46,19 @@ export class AppComponent {
private promptEvent: any;
public hasMenu: boolean = false;
public workspace = undefined;
public mobileAndHeaderState: number = -1

public additionalProperties: Map<string, Map<string,string>> = new Map<string, Map<string, string>>();
public additionalTypes: Array<string>;
public properties: Array<string>; //array of properties (the keys in the propertiesMap)
public entitiesList: Array<Feature>; //list of entities that has been filtered
public entitiesAll: Array<Feature>; //all entities
public propertiesMap: Map<string, Array<Option>> = new Map(); //string of all properties (keys) and all values associated with this property

@ViewChild('searchBar', { read: ElementRef, static: true })
searchBar: ElementRef;

constructor(
private additionalPropertiesService: FiltersAdditionalPropertiesService,
private http: HttpClient,
protected languageService: LanguageService,
private configService: ConfigService,
private renderer: Renderer2,
Expand All @@ -64,10 +75,10 @@ export class AppComponent {
this.readDescriptionConfig();

this.detectOldBrowser();
this.useEmbeddedVersion = this.configService.getConfig('useEmbeddedVersion') === undefined ? false : true;
this.showSimpleFilters = this.configService.getConfig('useEmbeddedVersion.simpleFilters') === undefined ? false : true;
this.showSimpleFeatureList = this.configService.getConfig('useEmbeddedVersion.simpleFeatureList') === undefined ? false : true;
this.hasHeader = this.configService.getConfig('header.hasHeader') !== undefined && this.configService.getConfig('useEmbeddedVersion') === undefined ?
this.useEmbeddedVersion = this.configService.getConfig('embeddedVersion.useEmbeddedVersion') === undefined ? false : this.configService.getConfig('embeddedVersion.useEmbeddedVersion');

Check failure on line 78 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

This line has a length of 188. Maximum allowed is 140

Check failure on line 78 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

This line has a length of 188. Maximum allowed is 140
this.showSimpleFilters = this.configService.getConfig('embeddedVersion.simpleFilters') === undefined ? false : true;
this.showSimpleFeatureList = this.configService.getConfig('embeddedVersion.simpleFeatureList') === undefined ? false : true;
this.hasHeader = this.configService.getConfig('header.hasHeader') !== undefined && !this.useEmbeddedVersion ?
this.configService.getConfig('header.hasHeader') : false;

this.hasFooter = this.configService.getConfig('hasFooter') === undefined ? false :
Expand All @@ -81,6 +92,32 @@ export class AppComponent {
this.pwaService.checkForUpdates();
}

public async ngOnInit() {

Check warning on line 95 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Lifecycle interface 'OnInit' should be implemented for method 'ngOnInit'. (https://angular.io/styleguide#style-09-01)

Check warning on line 95 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Lifecycle interface 'OnInit' should be implemented for method 'ngOnInit'. (https://angular.io/styleguide#style-09-01)
// get all the types from terrAPI
await this.getTypesFromTerrAPI().then((terrAPITypes: Array<string>) => {
this.terrAPITypes = terrAPITypes;
});
}

/**
* @description Get an array containg all the types from terrAPI
* @returns An array of strings containing the types of terrAPI
*/
private async getTypesFromTerrAPI(): Promise<Array<string>> {
// construct the URL
const url: string = this.terrAPIBaseURL + "types";

let response: Array<string>;

// make the call to terrAPI and return the the types
await this.http.get<Array<string>>(url).pipe(map((terrAPITypes: Array<string>) => {
response = terrAPITypes;
return terrAPITypes;
})).toPromise();

return response;
}

private readTitleConfig() {
this.languageService.translate.get(this.configService.getConfig('title')).subscribe(title => {
if (title) {
Expand Down Expand Up @@ -145,8 +182,31 @@ export class AppComponent {
}
}

setSelectedWorkspace(workspace: Workspace) {
async setSelectedWorkspace(workspace: Workspace) {
this.workspace = workspace;
this.entitiesAll = this.workspace.entityStore.entities$.getValue() as Array<Feature>;
this.entitiesList = this.workspace.entityStore.entities$.getValue() as Array<Feature>;

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

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

await this.initializeAdditionalTypes().then((types: Array<string>) => {
this.additionalTypes = types;
console.log("additionalTypes11 ", this.additionalTypes);
});

this.initializeAdditionalProperties();
console.log("additionalProperties11 ", this.additionalProperties);

}

setClickedEntities(features: Feature[]) {
Expand All @@ -157,4 +217,100 @@ export class AppComponent {
this.features = event;
}


private async initializeAdditionalTypes() {
//the 3 sections where we can define terrAPI types in the config file
const listAttributesConfig = this.configService.getConfig('embeddedVersion.simpleFeatureList.attributeOrder');
const sortAttributesConfig = this.configService.getConfig('embeddedVersion.simpleFeatureList.sortBy.attributes');
const filtersAttributesConfig = this.configService.getConfig('embeddedVersion.simpleFilters.filters');

let terrAPIAttributes: Array<string> = [];
if(sortAttributesConfig){
for(let attribute of sortAttributesConfig) {
let type = attribute["type"];
if(type && !this.properties.includes(type) && !terrAPIAttributes.includes(type) && this.terrAPITypes.includes(type)) terrAPIAttributes.push(type);

Check failure on line 231 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

This line has a length of 154. Maximum allowed is 140

Check failure on line 231 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

This line has a length of 154. Maximum allowed is 140
}
}

if(listAttributesConfig){
for(let entry of listAttributesConfig){
if(entry["personalizedFormatting"]){
let attributeList: Array<string> = entry["personalizedFormatting"].match(/(?<=\[)(.*?)(?=\])/g);
attributeList.forEach(type => {
if(type && !this.properties.includes(type) && !terrAPIAttributes.includes(type) && this.terrAPITypes.includes(type)) terrAPIAttributes.push(type);

Check failure on line 240 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

This line has a length of 158. Maximum allowed is 140

Check failure on line 240 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

This line has a length of 158. Maximum allowed is 140
})

Check failure on line 241 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Missing semicolon

Check failure on line 241 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Missing semicolon
}else{
let type = entry["attributeName"];
if(type && !this.properties.includes(type) && !terrAPIAttributes.includes(type) && this.terrAPITypes.includes(type)) terrAPIAttributes.push(type);

Check failure on line 244 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

This line has a length of 156. Maximum allowed is 140

Check failure on line 244 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

This line has a length of 156. Maximum allowed is 140
}
}
}

if(filtersAttributesConfig){
for(let filter of filtersAttributesConfig){
let type = filter["type"];
if(type && !this.properties.includes(type) && !terrAPIAttributes.includes(type) && this.terrAPITypes.includes(type)) terrAPIAttributes.push(type);

Check failure on line 252 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

This line has a length of 154. Maximum allowed is 140

Check failure on line 252 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

This line has a length of 154. Maximum allowed is 140
}
}

for(let type of terrAPIAttributes){
let geometryType;
let url = "https://geoegl.msp.gouv.qc.ca/apis/terrapi/" + type + "?geometry=1&limit=1";

await this.getGeometryType(url).then((type: Array<Feature>) => {
geometryType = type["features"][0]["geometry"]["type"];
return geometryType;
});

//remove it if it is neither a polygon or a multipolygon, since these types won't work
if(geometryType.toLowerCase() !== "polygon" && geometryType.toLowerCase() !== "multipolygon"){
terrAPIAttributes = terrAPIAttributes.filter(attribute => attribute !== type);
}
}

return terrAPIAttributes;
}

private async initializeAdditionalProperties() {
for(let entity of this.entitiesAll){
await this.sleep(500);
let coords: string = entity.geometry.coordinates.join(",");
let typeMap = new Map<string, string>();
for(let type of this.additionalTypes){
await this.checkTerrAPI(type, coords).then(response => {
if(response.features[0]){
const name = response.features[0]["properties"]["nom"];
typeMap.set(type, name);
}
});
}
this.additionalProperties.set(coords, typeMap);
}
console.log("additionalProperties initialized ", this.additionalProperties);
console.log("properties ", this.properties);
// this.additionalTypes =

Check failure on line 291 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Trailing spaces not allowed

Check failure on line 291 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Trailing spaces not allowed
this.additionalPropertiesService.emitEvent(this.additionalProperties);
}

private sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

async checkTerrAPI(attribute: string, coordinates: string){
let url: string = this.terrAPIBaseURL + "locate?type=" + attribute + "&loc=" + coordinates;

return await this.http.get<FeatureCollection>(url).toPromise();
}

async getGeometryType(url: string){
let response: Array<Feature>;

await this.http.get<Array<Feature>>(url).pipe(map((features: Array<Feature>) => {
response = features;
return features;
})).toPromise();

return response;
}

}
Loading

0 comments on commit 6387af5

Please sign in to comment.