From a093d9a8c52707d60c3b4532158fcdc3f9608af0 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Fri, 23 Dec 2022 10:30:54 +0100 Subject: [PATCH 01/44] feat(front): wip sites_groups component and svc --- .../components/modules/modules.component.html | 2 +- .../components/modules/modules.component.ts | 8 +-- .../monitoring-sitesgroups.component.css | 0 .../monitoring-sitesgroups.component.html | 9 ++++ .../monitoring-sitesgroups.component.ts | 49 +++++++++++++++++++ frontend/app/gnModule.module.ts | 23 +++++---- frontend/app/services/sites.service.ts | 17 +++++++ 7 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css create mode 100644 frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html create mode 100644 frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts create mode 100644 frontend/app/services/sites.service.ts diff --git a/frontend/app/components/modules/modules.component.html b/frontend/app/components/modules/modules.component.html index 611c18166..72863fc15 100644 --- a/frontend/app/components/modules/modules.component.html +++ b/frontend/app/components/modules/modules.component.html @@ -14,7 +14,7 @@

{{titleModule}}

{{description}}
-
diff --git a/frontend/app/components/modules/modules.component.ts b/frontend/app/components/modules/modules.component.ts index 9a45f8f00..b538c7afe 100644 --- a/frontend/app/components/modules/modules.component.ts +++ b/frontend/app/components/modules/modules.component.ts @@ -68,9 +68,9 @@ export class ModulesComponent implements OnInit { this.currentUser["cruved_objects"] = {}; } - onAccessSitesClick(modules) { - console.log("accès aux sites avec droits ") - console.log(modules) - } + // onAccessSitesClick(modules) { + // console.log("accès aux sites avec droits ") + // console.log(modules) + // } } diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html new file mode 100644 index 000000000..85afaac99 --- /dev/null +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -0,0 +1,9 @@ +
+ + + +
diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts new file mode 100644 index 000000000..00e3634be --- /dev/null +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -0,0 +1,49 @@ +import { Component, OnInit } from "@angular/core"; +import { SitesService } from "../../services/sites.service"; +import { GeoJSON } from "leaflet"; + +interface SitesGroups { + comments?: string; + data?: any; + geom_geojson: any; + id_sites_group: number; + nb_sites: number; + nb_visits: number; + sites_group_code: string; + sites_group_description?: string; + sites_group_name: string; + uuid_sites_group: string; +} + +interface PaginatedSitesGroup { + count: number; + limit: number; + offset: number; + items: SitesGroups[]; +} + +@Component({ + selector: "monitoring-sitesgroups", + templateUrl: "./monitoring-sitesgroups.component.html", + styleUrls: ["./monitoring-sitesgroups.component.css"], +}) +export class MonitoringSitesGroupsComponent implements OnInit { + sitesGroups: GeoJSON; + constructor(private _sites_service: SitesService) {} + ngOnInit() { + console.log("yolo"); + this._sites_service + .getSitesGroups() + .subscribe((data: PaginatedSitesGroup) => { + this.sitesGroups = { + features: data.items.map((group) => { + group["id"] = group.id_sites_group; + group["type"] = "Feature"; + return group; + }), + type: "FeatureCollection", + }; + console.log(this.sitesGroups); + }); + } +} diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index 64fecadc7..6e0253846 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -27,13 +27,12 @@ import { MonitoringPropertiesComponent } from "./components/monitoring-propertie import { MonitoringDatatableComponent } from "./components/monitoring-datatable/monitoring-datatable.component"; import { MatSlideToggleModule } from "@angular/material/slide-toggle"; -import { MatFormFieldModule} from "@angular/material/form-field"; -import { MatAutocompleteModule} from "@angular/material/autocomplete"; -import { MatSelectModule} from "@angular/material/select"; -import { MatInputModule} from "@angular/material/input"; - - - +import { MatFormFieldModule } from "@angular/material/form-field"; +import { MatAutocompleteModule } from "@angular/material/autocomplete"; +import { MatSelectModule } from "@angular/material/select"; +import { MatInputModule } from "@angular/material/input"; +import { MonitoringSitesGroupsComponent } from "./components/monitoring-sitesgroups/monitoring-sitesgroups.component"; +import { SitesService } from "./services/sites.service"; // my module routing const routes: Routes = [ @@ -41,9 +40,9 @@ const routes: Routes = [ { path: "", component: ModulesComponent }, /** module */ - { path: 'module/:moduleCode', component: MonitoringObjectComponent }, + { path: "module/:moduleCode", component: MonitoringObjectComponent }, /** create module */ - { path: 'module', component: MonitoringObjectComponent }, + { path: "module", component: MonitoringObjectComponent }, /** object */ { @@ -55,6 +54,10 @@ const routes: Routes = [ path: "create_object/:moduleCode/:objectType", component: MonitoringObjectComponent, }, + { + path: "sites_groups", + component: MonitoringSitesGroupsComponent, + }, ]; @NgModule({ @@ -69,6 +72,7 @@ const routes: Routes = [ MonitoringListComponent, MonitoringPropertiesComponent, MonitoringDatatableComponent, + MonitoringSitesGroupsComponent, ], imports: [ GN2CommonModule, @@ -92,6 +96,7 @@ const routes: Routes = [ DataUtilsService, ConfigService, MonitoringObjectService, + SitesService, ], bootstrap: [ModulesComponent], schemas: [ diff --git a/frontend/app/services/sites.service.ts b/frontend/app/services/sites.service.ts new file mode 100644 index 000000000..f34ffeb00 --- /dev/null +++ b/frontend/app/services/sites.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from "@angular/core"; + +import { CacheService } from "./cache.service"; +import { ConfigService } from "./config.service"; +import { HttpClient } from "@angular/common/http"; + + +@Injectable() +export class SitesService { + constructor( + private _cacheService: CacheService + ) {} + + getSitesGroups() { + return this._cacheService.request("get", `sites_groups`); + } +} From ce6403929221fe89fd64887deeeab49f47743afe Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Mon, 26 Dec 2022 20:38:43 +0100 Subject: [PATCH 02/44] WIP feat(front): DataTable sites_groups - Table with specific data value (OK) - Table with sort column (OK) - Datatable , select row event and change color (wip). Reviewed-by: andriac [Refs ticket]: #4 --- .../monitoring-sitesgroups.component.css | 67 +++++++ .../monitoring-sitesgroups.component.html | 118 +++++++++++- .../monitoring-sitesgroups.component.ts | 171 +++++++++++++++++- 3 files changed, 353 insertions(+), 3 deletions(-) diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css index e69de29bb..05190a9e3 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css @@ -0,0 +1,67 @@ +.flex-container { + background-color: rgb(240, 240, 240); + display: flex; + } + + .flex-container > div { + width: 50%; + padding: 10px; + margin: 10px; + } + + .flex-container > div:first-child { + margin-right: 0; + } + + .scroll { + overflow-y: scroll; + } + + + :host ::ng-deep .cadre { + background-color: white; + /* border: 1px solid grey;*/ + border-radius: 5px; + padding: 5px; + margin: 5px; + /* display: inline-block; */ + } + + + /* TABLE */ + + .cell-link { + cursor: pointer; +} + +:host::ng-deep .datatable-body-row.active .datatable-row-group { + background-color: rgb(117, 227, 118) !important; +} + +.link:hover { + background-color: rgba(0, 0, 0, 0.2) !important; + transition: background-color 0.5; +} + +.link { + display: inline; + transition: background-color 0.5s; + border-radius: 5px; +} + +.header-filter-span > input { + width: 100%; +} + +.header-sort-span { + /* width: 100%; */ + cursor: pointer; + text-overflow: ellipsis; + overflow: hidden; + white-space:nowrap +} + + +.header-sort-span:hover { + background-color: rgb(245, 245, 245); +} diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index 85afaac99..7284bb254 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -1,4 +1,5 @@ -
+
+
+
+ + + +
+
\ No newline at end of file diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 00e3634be..90f71aa52 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -1,7 +1,13 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit, Input, + Output, + EventEmitter, + ViewChild, + SimpleChanges } from "@angular/core"; import { SitesService } from "../../services/sites.service"; import { GeoJSON } from "leaflet"; +import { DatatableComponent } from "@swimlane/ngx-datatable"; +import { Subject } from "rxjs"; interface SitesGroups { comments?: string; data?: any; @@ -28,7 +34,26 @@ interface PaginatedSitesGroup { styleUrls: ["./monitoring-sitesgroups.component.css"], }) export class MonitoringSitesGroupsComponent implements OnInit { + + @ViewChild(DatatableComponent) table: DatatableComponent; + @Input() rowStatus: Array; + @Output() rowStatusChange = new EventEmitter(); + @Output() bEditChanged = new EventEmitter(); + objectsStatus; + groupSiteId; + + private filterSubject: Subject = new Subject(); + selected = []; + filters = {}; + + + listAllColName:{"name":string,"prop":string}[]=[]; + dataTable; + rows; + columns; + sitesGroups: GeoJSON; + constructor(private _sites_service: SitesService) {} ngOnInit() { console.log("yolo"); @@ -43,7 +68,149 @@ export class MonitoringSitesGroupsComponent implements OnInit { }), type: "FeatureCollection", }; - console.log(this.sitesGroups); + // console.log(this.sitesGroups); + this.getDataTable() + this.colsTable() + // console.log(this.listAllColName) + this.columns = this.listAllColName + this.rows=this.dataTable + console.log("rows",this.rows) + console.log("columns",this.columns) + this.groupSiteId= this.sitesGroups.features[0].id + console.log("this.groupSiteId",this.groupSiteId) + this.initObjectsStatus() }); + + } + + + getDataTable(){ + this.dataTable = this.sitesGroups.features.map(groupSite => { + let { comments,data,geometry,uuid_sites_group,type, ... dataTable } = groupSite + return dataTable + }) ; + // console.log(this.dataTable) + } + + colsTable(){ + const arr= Object.keys(this.dataTable[0]); + console.log("arr",arr) + arr.forEach(element => + this.listAllColName.push({"name": element,"prop": element})); + return this.listAllColName + } + + initObjectsStatus() { + const objectsStatus = {}; + // for (const childrenType of Object.keys(this.obj.children)) { + objectsStatus["sites_groups"] = this.sitesGroups.features.map( + (groupSite) => { + return { + id: groupSite.id, + selected: false, + visible: true, + current: false, + }; + } + ); + console.log("objectsStatus",objectsStatus) + // } + + // init site status + if (this.groupSiteId) { + objectsStatus["sites_groups"] = []; + this.sitesGroups.features.forEach((f) => { + // determination du site courrant + let cur = false; + if (f.id_sites_group == this.groupSiteId) { + cur = true; + } + + objectsStatus["sites_groups"].push({ + id: f.id_sites_group, + selected: false, + visible: true, + current: cur, + }); + }); + } + + this.objectsStatus = objectsStatus; + console.log("objectsStatus after init",objectsStatus) + } + + onRowClick(event) { + console.log('Select Event', event, this.selected); + if (!(event && event.type === "click")) { + return; + } + const id = event.row && event.row.id; + + if (!this.rowStatus) { + return; + } + + this.rowStatus.forEach((status) => { + const bCond = status.id === id; + status["selected"] = bCond && !status["selected"]; + }); + + this.setSelected(); + this.rowStatusChange.emit(this.rowStatus); + console.log("after click rowStatus",this.rowStatus) + console.log("after click selected",this.selected) + console.log("after click table",this.table) + } + + setSelected() { + // this.table._internalRows permet d'avoir les ligne triées et d'avoir les bons index + + if (!this.rowStatus) { + return; + } + + const status_selected = this.rowStatus.find((status) => status.selected); + if (!status_selected) { + return; + } + + const index_row_selected = this.table._internalRows.findIndex( + (row) => row.id === status_selected.id + ); + if (index_row_selected === -1) { + return; + } + + this.selected = [this.table._internalRows[index_row_selected]]; + this.table.offset = Math.floor(index_row_selected / this.table._limit); + } + + + // ngOnChanges(changes: SimpleChanges) { + // console.log("inside ngOnChanges") + // for (const propName of Object.keys(changes)) { + // const chng = changes[propName]; + // const cur = chng.currentValue; + // const pre = chng.currentValue; + // switch (propName) { + // case "rowStatus": + // this.setSelected(); + // break; + // // case "child0": + // // this.customColumnComparator = this.customColumnComparator_(); + // // break; + // } + // } + // } + + + + // TEST + onSelect({ selected }) { + console.log('Select Event', selected, this.selected); + } + + onActivate(event) { + console.log('Activate Event', event); } } From 3ee07bcc0cb318337b12f9664ef890778956c8f7 Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Tue, 27 Dec 2022 14:53:01 +0100 Subject: [PATCH 03/44] feat(front): Datatable format and selected row - Get and display data from group_site database (OK) - Selecting row and get id of row table (OK) Improve : - improve assign colname table outside the component (maybe into the class folder ?) Todo/next: - Filtering table - Add action column to table - refactor code by creating component for the ngx-datable in order to reuse component for other data Reviewed-by: andriac [Refs ticket]: #4 --- .../monitoring-sitesgroups.component.css | 81 ++++---- .../monitoring-sitesgroups.component.html | 92 +-------- .../monitoring-sitesgroups.component.ts | 193 +++++++++++------- 3 files changed, 159 insertions(+), 207 deletions(-) diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css index 05190a9e3..2a6ca24f0 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css @@ -1,67 +1,64 @@ .flex-container { - background-color: rgb(240, 240, 240); - display: flex; - } - - .flex-container > div { - width: 50%; - padding: 10px; - margin: 10px; - } - - .flex-container > div:first-child { - margin-right: 0; - } + background-color: rgb(240, 240, 240); + display: flex; +} - .scroll { - overflow-y: scroll; - } - +.flex-container > div { + width: 50%; + padding: 10px; + margin: 10px; +} - :host ::ng-deep .cadre { - background-color: white; - /* border: 1px solid grey;*/ - border-radius: 5px; - padding: 5px; - margin: 5px; - /* display: inline-block; */ - } +.flex-container > div:first-child { + margin-right: 0; +} +.scroll { + overflow-y: scroll; +} - /* TABLE */ +:host ::ng-deep .cadre { + background-color: white; + /* border: 1px solid grey;*/ + border-radius: 5px; + padding: 5px; + margin: 5px; + /* display: inline-block; */ +} + +/* TABLE */ - .cell-link { - cursor: pointer; +.cell-link { + cursor: pointer; } :host::ng-deep .datatable-body-row.active .datatable-row-group { - background-color: rgb(117, 227, 118) !important; + background-color: rgb(117, 227, 118) !important; } .link:hover { - background-color: rgba(0, 0, 0, 0.2) !important; - transition: background-color 0.5; + background-color: rgba(0, 0, 0, 0.2) !important; + transition: background-color 0.5; } .link { - display: inline; - transition: background-color 0.5s; - border-radius: 5px; + display: inline; + transition: background-color 0.5s; + border-radius: 5px; } .header-filter-span > input { - width: 100%; + width: 100%; } .header-sort-span { - /* width: 100%; */ - cursor: pointer; - text-overflow: ellipsis; - overflow: hidden; - white-space:nowrap + /* width: 100%; */ + cursor: pointer; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; } - .header-sort-span:hover { - background-color: rgb(245, 245, 245); + background-color: rgb(245, 245, 245); } diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index 7284bb254..4d4aaf2e3 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -24,7 +24,7 @@ [rows]="rows" [columns]="columns" [selected]="selected" - (activate)="onActivate($event)" + selectionType="single" (select)="onSelect($event)" [messages]= "{ emptyMessage: 'Pas de données disponibles', @@ -32,94 +32,6 @@ selectedMessage: 'selection' }" > - + \ No newline at end of file diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 90f71aa52..9c1947410 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -1,8 +1,12 @@ -import { Component, OnInit, Input, +import { + Component, + OnInit, + Input, Output, EventEmitter, ViewChild, - SimpleChanges } from "@angular/core"; + SimpleChanges, +} from "@angular/core"; import { SitesService } from "../../services/sites.service"; import { GeoJSON } from "leaflet"; @@ -28,15 +32,22 @@ interface PaginatedSitesGroup { items: SitesGroups[]; } +enum columnNameSiteGroup { + nb_sites = "Nb. sites", + nb_visits = "Nb. visites", + sites_group_code = "Code", + sites_group_name = "Nom", +} + @Component({ selector: "monitoring-sitesgroups", templateUrl: "./monitoring-sitesgroups.component.html", styleUrls: ["./monitoring-sitesgroups.component.css"], }) export class MonitoringSitesGroupsComponent implements OnInit { - @ViewChild(DatatableComponent) table: DatatableComponent; - @Input() rowStatus: Array; + rowStatus: Array; + // @Input() rowStatus: Array; @Output() rowStatusChange = new EventEmitter(); @Output() bEditChanged = new EventEmitter(); objectsStatus; @@ -46,8 +57,7 @@ export class MonitoringSitesGroupsComponent implements OnInit { selected = []; filters = {}; - - listAllColName:{"name":string,"prop":string}[]=[]; + listAllColName: { name: string; prop: string }[] = []; dataTable; rows; columns; @@ -69,51 +79,65 @@ export class MonitoringSitesGroupsComponent implements OnInit { type: "FeatureCollection", }; // console.log(this.sitesGroups); - this.getDataTable() - this.colsTable() + this.getDataTable(); + this.colsTable(); // console.log(this.listAllColName) - this.columns = this.listAllColName - this.rows=this.dataTable - console.log("rows",this.rows) - console.log("columns",this.columns) - this.groupSiteId= this.sitesGroups.features[0].id - console.log("this.groupSiteId",this.groupSiteId) - this.initObjectsStatus() + this.columns = this.listAllColName; + this.rows = this.dataTable; + console.log("rows", this.rows); + console.log("columns", this.columns); + this.groupSiteId = this.sitesGroups.features[0].id; + console.log("this.groupSiteId", this.groupSiteId); + this.initObjectsStatus(); }); - } - - getDataTable(){ - this.dataTable = this.sitesGroups.features.map(groupSite => { - let { comments,data,geometry,uuid_sites_group,type, ... dataTable } = groupSite - return dataTable - }) ; - // console.log(this.dataTable) + getDataTable() { + this.dataTable = this.sitesGroups.features.map((groupSite) => { + let { + comments, + data, + geometry, + uuid_sites_group, + type, + id_sites_group, + sites_group_description, + ...dataTable + } = groupSite; + return dataTable; + }); + // console.log(this.dataTable) } - colsTable(){ - const arr= Object.keys(this.dataTable[0]); - console.log("arr",arr) - arr.forEach(element => - this.listAllColName.push({"name": element,"prop": element})); - return this.listAllColName + colsTable() { + const arr = Object.keys(this.dataTable[0]); + console.log("arr", arr); + arr.forEach((element) => { + this.listAllColName.push({ + name: + element in ["id", "id_group_site"] + ? element + : columnNameSiteGroup[element], + prop: element, + }); + }); + return this.listAllColName; } initObjectsStatus() { const objectsStatus = {}; // for (const childrenType of Object.keys(this.obj.children)) { objectsStatus["sites_groups"] = this.sitesGroups.features.map( - (groupSite) => { - return { - id: groupSite.id, - selected: false, - visible: true, - current: false, - }; - } - ); - console.log("objectsStatus",objectsStatus) + (groupSite) => { + return { + id: groupSite.id, + selected: false, + visible: true, + current: false, + }; + } + ); + console.log("objectsStatus", objectsStatus); // } // init site status @@ -122,12 +146,12 @@ export class MonitoringSitesGroupsComponent implements OnInit { this.sitesGroups.features.forEach((f) => { // determination du site courrant let cur = false; - if (f.id_sites_group == this.groupSiteId) { + if (f.id == this.groupSiteId) { cur = true; } objectsStatus["sites_groups"].push({ - id: f.id_sites_group, + id: f.id, selected: false, visible: true, current: cur, @@ -136,19 +160,25 @@ export class MonitoringSitesGroupsComponent implements OnInit { } this.objectsStatus = objectsStatus; - console.log("objectsStatus after init",objectsStatus) + console.log("objectsStatus after init", objectsStatus); + this.rowStatus = this.objectsStatus["sites_groups"]; } - onRowClick(event) { - console.log('Select Event', event, this.selected); - if (!(event && event.type === "click")) { - return; - } - const id = event.row && event.row.id; + // ICI le select renvoyé correspond directement aux valeurs de la ligne sélectionné et non à l'event + // permet de simplifier la fonction et pas besoin de checke si l'event est un "click" ou non + onSelect({ selected }) { + console.log("Select Event", selected, this.selected); + console.log("this.table", this.table); + console.log(this.table._internalRows); + + console.log("event.id", selected.id); + const id = selected[0].id; + console.log("event.row after check event.type", selected); if (!this.rowStatus) { return; } + console.log("this.rowStatus after check rowStatus", this.rowStatus); this.rowStatus.forEach((status) => { const bCond = status.id === id; @@ -157,14 +187,14 @@ export class MonitoringSitesGroupsComponent implements OnInit { this.setSelected(); this.rowStatusChange.emit(this.rowStatus); - console.log("after click rowStatus",this.rowStatus) - console.log("after click selected",this.selected) - console.log("after click table",this.table) + console.log("after click rowStatus", this.rowStatus); + console.log("after click selected", this.selected); + console.log("after click table", this.table); } setSelected() { // this.table._internalRows permet d'avoir les ligne triées et d'avoir les bons index - + console.log("Inside setSelected", this.rowStatus); if (!this.rowStatus) { return; } @@ -185,32 +215,45 @@ export class MonitoringSitesGroupsComponent implements OnInit { this.table.offset = Math.floor(index_row_selected / this.table._limit); } + // Pour l'instant fonction non active + ngOnChanges(changes: SimpleChanges) { + console.log("inside ngOnChanges"); + for (const propName of Object.keys(changes)) { + const chng = changes[propName]; + const cur = chng.currentValue; + const pre = chng.currentValue; + switch (propName) { + case "rowStatus": + this.setSelected(); + break; + // case "child0": + // this.customColumnComparator = this.customColumnComparator_(); + // break; + } + } + } - // ngOnChanges(changes: SimpleChanges) { - // console.log("inside ngOnChanges") - // for (const propName of Object.keys(changes)) { - // const chng = changes[propName]; - // const cur = chng.currentValue; - // const pre = chng.currentValue; - // switch (propName) { - // case "rowStatus": - // this.setSelected(); - // break; - // // case "child0": - // // this.customColumnComparator = this.customColumnComparator_(); - // // break; - // } + ////////////////////////////////////// + // NON utilisé car le databinding (selected)=onSelect($event) suffit par rapport au but recherché + ///////////////////////////////////////////////// + // onRowClick(event) { + // console.log("inside onRowClick- event",event) + // if (!(event && event.type === "click")) { + // return; // } - // } - + // console.log("inside onRowClick- event.row",event.row) + // const id = event.row && event.row.id; + // if (!this.rowStatus) { + // return; + // } - // TEST - onSelect({ selected }) { - console.log('Select Event', selected, this.selected); - } + // this.rowStatus.forEach((status) => { + // const bCond = status.id === id; + // status["selected"] = bCond && !status["selected"]; + // }); - onActivate(event) { - console.log('Activate Event', event); - } + // this.setSelected(); + // this.rowStatusChange.emit(this.rowStatus); + // } } From 1ec9c795bfd950bda0f85b3aaa8524376c35797c Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Tue, 27 Dec 2022 19:23:25 +0100 Subject: [PATCH 04/44] feat(front): Filtering table (OK) Function filtering is working on each column Button filtering hide/display filter inputs (OK) TODO: - check for "help" icon and description for each column if description present - Check if multiple rows and pages if it's working Reviewed-by: andriac [Refs ticket]: #4 --- .../monitoring-sitesgroups.component.css | 13 ++ .../monitoring-sitesgroups.component.html | 74 +++++++++++- .../monitoring-sitesgroups.component.ts | 114 +++++++++++++++++- 3 files changed, 195 insertions(+), 6 deletions(-) diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css index 2a6ca24f0..12a5bfd0b 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css @@ -62,3 +62,16 @@ .header-sort-span:hover { background-color: rgb(245, 245, 245); } + +.icon-sort { + font-size: 1.2em; + float: right; +} + +:host::ng-deep .sort-btn { + display: none !important; +} + +.custom-dt { + box-shadow: none !important; +} diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index 4d4aaf2e3..8708e6649 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -12,6 +12,22 @@ +
+ + + + +
+ > + + + + + + + + + + + + + + + + +
+ + + help + {{ column.name }} +
+
+ +
+
\ No newline at end of file diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 9c1947410..02c126b3f 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -12,6 +12,7 @@ import { GeoJSON } from "leaflet"; import { DatatableComponent } from "@swimlane/ngx-datatable"; import { Subject } from "rxjs"; +import {debounceTime } from "rxjs/operators"; interface SitesGroups { comments?: string; data?: any; @@ -56,12 +57,23 @@ export class MonitoringSitesGroupsComponent implements OnInit { private filterSubject: Subject = new Subject(); selected = []; filters = {}; + row_save; - listAllColName: { name: string; prop: string }[] = []; + + listAllColName: { name: string; prop: string,description?:string }[] = []; dataTable; rows; columns; + // child0 = { + // "config":{ + // "display_filter":false + // } + // } + + // Est ce qu'un simple boolean ne convient pas ? + displayFilter:boolean = false; + sitesGroups: GeoJSON; constructor(private _sites_service: SitesService) {} @@ -88,8 +100,10 @@ export class MonitoringSitesGroupsComponent implements OnInit { console.log("columns", this.columns); this.groupSiteId = this.sitesGroups.features[0].id; console.log("this.groupSiteId", this.groupSiteId); + this.initDatatable(); this.initObjectsStatus(); }); + } getDataTable() { @@ -119,6 +133,7 @@ export class MonitoringSitesGroupsComponent implements OnInit { ? element : columnNameSiteGroup[element], prop: element, + description: undefined }); }); return this.listAllColName; @@ -165,16 +180,15 @@ export class MonitoringSitesGroupsComponent implements OnInit { } // ICI le select renvoyé correspond directement aux valeurs de la ligne sélectionné et non à l'event - // permet de simplifier la fonction et pas besoin de checke si l'event est un "click" ou non + // permet de simplifier la fonction et pas besoin de check si l'event est un "click" ou non onSelect({ selected }) { - console.log("Select Event", selected, this.selected); + console.log("Select Row", selected, this.selected); console.log("this.table", this.table); console.log(this.table._internalRows); - console.log("event.id", selected.id); + console.log("selected[0].id", selected[0].id); const id = selected[0].id; - console.log("event.row after check event.type", selected); if (!this.rowStatus) { return; } @@ -233,6 +247,19 @@ export class MonitoringSitesGroupsComponent implements OnInit { } } + // TEST + // onSelect({ selected }) { + // console.log('Select Event', selected, this.selected); + // } + + // onActivate(event) { + // console.log("Activate Event", event); + // } + + // if (!this.rowStatus) { + // return; + // } + ////////////////////////////////////// // NON utilisé car le databinding (selected)=onSelect($event) suffit par rapport au but recherché ///////////////////////////////////////////////// @@ -256,4 +283,81 @@ export class MonitoringSitesGroupsComponent implements OnInit { // this.setSelected(); // this.rowStatusChange.emit(this.rowStatus); // } + + ////////////////////////////////////: + // WIP : fonctions liés à des classes basées sur ce qui se faisait anciennement avec le module code en parent de tout + // A l'adapter pour coller avec l'architecture actuelle + /////////////////////// + + initDatatable() { + console.log("Inside initDatatable") + this.filters = {}; + this.filterSubject.pipe(debounceTime(500)).subscribe(() => { + this.filter(); + }); + + // this.customColumnComparator = this.customColumnComparator_(); + this.row_save = this.rows.map((e) => e); + // on declenche les filtres (si filtre par defaut) + setTimeout(() => { + this.filter(true); + }, 500); + } + + filterInput($event) { + this.filterSubject.next(); + } + + sort() {} + + filter(bInitFilter = false) { + // filter all + + let bChange = false; + const temp = this.row_save.filter((row, index) => { + let bCondVisible = true; + for (const key of Object.keys(this.filters)) { + let val = this.filters[key]; + if ([null, undefined].includes(val)) { + continue; + } + val = String(val).toLowerCase(); + const vals = val.split(" "); + for (const v of vals) { + bCondVisible = + bCondVisible && (String(row[key]) || "").toLowerCase().includes(v); + } + } + + if (!this.rowStatus) { + return bCondVisible; + } + bChange = bChange || bCondVisible !== this.rowStatus[index].visible; + this.rowStatus[index]["visible"] = bCondVisible; + this.rowStatus[index]["selected"] = + this.rowStatus[index]["selected"] && bCondVisible; + return bCondVisible; + }); + + if (bChange || bInitFilter) { + this.rowStatusChange.emit(this.rowStatus); + } + // update the rows + this.rows = temp; + // Whenever the filter changes, always go back to the first page + this.table.offset = 0; + this.setSelected(); + } + +// TODO: TO REPLACE WITH EFFECTIVE FUNCTION +navigateToDetail(row){ + console.log("Inside navigateToDetail on eye icon",row) +} + +navigateToAddChildren(_,rowId){ + console.log("Inside navigateToAddChildren:",rowId) +} + + + } From 673c18018da4f145ff6b41afda8f0a0ba74936f9 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Mon, 2 Jan 2023 16:35:38 +0100 Subject: [PATCH 05/44] feat(front): wip server pagination & filtering --- .../monitoring-sitesgroups.component.html | 6 +- .../monitoring-sitesgroups.component.ts | 117 +++++++++++------- frontend/app/services/sites.service.ts | 4 +- 3 files changed, 80 insertions(+), 47 deletions(-) diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index 8708e6649..20df7295d 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -36,7 +36,10 @@ [headerHeight]="'auto'" [footerHeight]="50" [rowHeight]="40" - [limit]="10" + [externalPaging]="true" + [count]="page.count" + [offset]="page.offset" + [limit]="page.limit" [rows]="rows" [columns]="columns" [selected]="selected" @@ -47,6 +50,7 @@ totalMessage: 'total', selectedMessage: 'selection' }" + (page)="setPage($event)" > { + this.page = {count: data.count, limit: data.limit, offset: data.offset - 1} this.sitesGroups = { features: data.items.map((group) => { group["id"] = group.id_sites_group; @@ -92,7 +110,7 @@ export class MonitoringSitesGroupsComponent implements OnInit { }; // console.log(this.sitesGroups); this.getDataTable(); - this.colsTable(); + this.listAllColName = this.colsTable(); // console.log(this.listAllColName) this.columns = this.listAllColName; this.rows = this.dataTable; @@ -100,12 +118,15 @@ export class MonitoringSitesGroupsComponent implements OnInit { console.log("columns", this.columns); this.groupSiteId = this.sitesGroups.features[0].id; console.log("this.groupSiteId", this.groupSiteId); - this.initDatatable(); this.initObjectsStatus(); }); } + setPage(e) { + this.getSites(e.offset + 1) + } + getDataTable() { this.dataTable = this.sitesGroups.features.map((groupSite) => { let { @@ -126,8 +147,9 @@ export class MonitoringSitesGroupsComponent implements OnInit { colsTable() { const arr = Object.keys(this.dataTable[0]); console.log("arr", arr); + const allColName: ColName[] = [] arr.forEach((element) => { - this.listAllColName.push({ + allColName.push({ name: element in ["id", "id_group_site"] ? element @@ -136,7 +158,7 @@ export class MonitoringSitesGroupsComponent implements OnInit { description: undefined }); }); - return this.listAllColName; + return allColName; } initObjectsStatus() { @@ -312,41 +334,48 @@ export class MonitoringSitesGroupsComponent implements OnInit { filter(bInitFilter = false) { // filter all - - let bChange = false; - const temp = this.row_save.filter((row, index) => { - let bCondVisible = true; - for (const key of Object.keys(this.filters)) { - let val = this.filters[key]; - if ([null, undefined].includes(val)) { - continue; - } - val = String(val).toLowerCase(); - const vals = val.split(" "); - for (const v of vals) { - bCondVisible = - bCondVisible && (String(row[key]) || "").toLowerCase().includes(v); - } - } - - if (!this.rowStatus) { - return bCondVisible; - } - bChange = bChange || bCondVisible !== this.rowStatus[index].visible; - this.rowStatus[index]["visible"] = bCondVisible; - this.rowStatus[index]["selected"] = - this.rowStatus[index]["selected"] && bCondVisible; - return bCondVisible; - }); - - if (bChange || bInitFilter) { - this.rowStatusChange.emit(this.rowStatus); - } - // update the rows - this.rows = temp; - // Whenever the filter changes, always go back to the first page - this.table.offset = 0; - this.setSelected(); + const oldFilters = this.filters + this.filters = Object.keys(oldFilters).reduce(function(r, e) { + if (![undefined, "", null].includes(oldFilters[e])) r[e] = oldFilters[e] + return r; + }, {}) + + //offset = 1 + this.getSites(1, this.filters) + // let bChange = false; + // const temp = this.row_save.filter((row, index) => { + // let bCondVisible = true; + // for (const key of Object.keys(this.filters)) { + // let val = this.filters[key]; + // if ([null, undefined].includes(val)) { + // continue; + // } + // val = String(val).toLowerCase(); + // const vals = val.split(" "); + // for (const v of vals) { + // bCondVisible = + // bCondVisible && (String(row[key]) || "").toLowerCase().includes(v); + // } + // } + + // if (!this.rowStatus) { + // return bCondVisible; + // } + // bChange = bChange || bCondVisible !== this.rowStatus[index].visible; + // this.rowStatus[index]["visible"] = bCondVisible; + // this.rowStatus[index]["selected"] = + // this.rowStatus[index]["selected"] && bCondVisible; + // return bCondVisible; + //}); + + // if (bChange || bInitFilter) { + // this.rowStatusChange.emit(this.rowStatus); + // } + // // update the rows + // this.rows = temp; + // // Whenever the filter changes, always go back to the first page + // this.table.offset = 0; + // this.setSelected(); } // TODO: TO REPLACE WITH EFFECTIVE FUNCTION diff --git a/frontend/app/services/sites.service.ts b/frontend/app/services/sites.service.ts index f34ffeb00..4a1cd0a60 100644 --- a/frontend/app/services/sites.service.ts +++ b/frontend/app/services/sites.service.ts @@ -11,7 +11,7 @@ export class SitesService { private _cacheService: CacheService ) {} - getSitesGroups() { - return this._cacheService.request("get", `sites_groups`); + getSitesGroups(offset=1, limit=10, params={}) { + return this._cacheService.request("get", `sites_groups`, {queryParams: {offset, limit, ...params}}); } } From c3194cc62f055dd70ed81e6cb92489b83d12d8b8 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Wed, 4 Jan 2023 15:34:20 +0100 Subject: [PATCH 06/44] feat(front): add sorting capability and fixes Fix: keep filters (sort and filters) on when changing pages Feat: remove useless id column Feat: add sorting --- .../monitoring-sitesgroups.component.html | 1 + .../monitoring-sitesgroups.component.ts | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index 20df7295d..b42894a17 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -51,6 +51,7 @@ selectedMessage: 'selection' }" (page)="setPage($event)" + (sort)="onSort($event)" > { - group["id"] = group.id_sites_group; group["type"] = "Feature"; return group; }), @@ -124,7 +123,7 @@ export class MonitoringSitesGroupsComponent implements OnInit { } setPage(e) { - this.getSites(e.offset + 1) + this.getSites(e.offset + 1, this.filters) } getDataTable() { @@ -330,7 +329,10 @@ export class MonitoringSitesGroupsComponent implements OnInit { this.filterSubject.next(); } - sort() {} + onSort($event) { + this.filters = {...this.filters, sort: $event.column.prop, sort_dir: $event.newValue} + this.getSites(1, this.filters) + } filter(bInitFilter = false) { // filter all From 4e0d1adef93303a5dc1ae5d0c5ebfb9477e23a77 Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Mon, 16 Jan 2023 10:56:30 +0100 Subject: [PATCH 07/44] fix(db): change trigger to constraint (migrations) Delete the trigger and create check constraint on id_nomenclature column Reviewed-by: andriacap [Refs ticket]: #3 --- .../b53bafb13ce8_create_bib_type_site.py | 26 ++++--------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/backend/gn_module_monitoring/migrations/b53bafb13ce8_create_bib_type_site.py b/backend/gn_module_monitoring/migrations/b53bafb13ce8_create_bib_type_site.py index b079edf9e..de4d92d60 100644 --- a/backend/gn_module_monitoring/migrations/b53bafb13ce8_create_bib_type_site.py +++ b/backend/gn_module_monitoring/migrations/b53bafb13ce8_create_bib_type_site.py @@ -36,27 +36,11 @@ def upgrade(): schema=monitorings_schema, ) - # FIXME: if sqlalchemy >= 1.4.32, it should work with postgresql_not_valid=True: cleaner - # op.create_check_constraint( - # "ck_bib_type_site_id_nomenclature_type_site", - # "bib_type_site", - # f"{nomenclature_schema}.check_nomenclature_type_by_mnemonique(id_nomenclature_type_site,'TYPE_SITE')", - # schema=monitorings_schema, - # postgresql_not_valid=True - # ) - statement = sa.text( - f""" - ALTER TABLE {monitorings_schema}.bib_type_site - ADD - CONSTRAINT ck_bib_type_site_id_nomenclature_type_site CHECK ( - {nomenclature_schema}.check_nomenclature_type_by_mnemonique( - id_nomenclature_type_site, 'TYPE_SITE' :: character varying - ) - ) NOT VALID - """ - ) - op.execute(statement) - + op.create_check_constraint( + "ck_bib_type_site_id_nomenclature", + "bib_type_site", + f"{nomenclature_schema}.check_nomenclature_type_by_mnemonique(id_nomenclature,'TYPE_SITE')", + schema=monitorings_schema) def downgrade(): op.drop_table("bib_type_site", schema=monitorings_schema) From 15a7a10ca54285c4410b9f061795aed4cfee2215 Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Tue, 17 Jan 2023 11:33:45 +0100 Subject: [PATCH 08/44] refactor: Custom type Geojson and group properties Create custom type geojson and build properties into marshmallow schema according to this type of Geojson [Refs ticket]: #3 --- .../monitoring/schemas.py | 5 ++ .../monitoring-sitesgroups.component.ts | 59 +++++++++++++------ 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/backend/gn_module_monitoring/monitoring/schemas.py b/backend/gn_module_monitoring/monitoring/schemas.py index f34066c55..59c76d13a 100644 --- a/backend/gn_module_monitoring/monitoring/schemas.py +++ b/backend/gn_module_monitoring/monitoring/schemas.py @@ -27,7 +27,12 @@ class Meta: model = TMonitoringSitesGroups exclude = ("geom_geojson",) + geometry = fields.Method("serialize_geojson", dump_only=True) + properties = fields.Method("group_properties_geojson") + + def group_properties_geojson(self, obj): + return {field: getattr(obj,field) for field in self.fields.keys() if field not in ("geometry","properties")} def serialize_geojson(self, obj): if obj.geom_geojson is not None: diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 3c44a4da5..4dbeb24e3 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -13,14 +13,13 @@ import { GeoJSON } from "leaflet"; import { DatatableComponent } from "@swimlane/ngx-datatable"; import { Subject } from "rxjs"; import {debounceTime } from "rxjs/operators"; +import { Feature, FeatureCollection } from "geojson"; const LIMIT = 10 - - -interface SitesGroups { +interface SitesGroups{ comments?: string; data?: any; - geom_geojson: any; + // geometry: any; id_sites_group: number; nb_sites: number; nb_visits: number; @@ -30,6 +29,14 @@ interface SitesGroups { uuid_sites_group: string; } + + +interface SitesGroupsExtended extends Omit { + // properties:Omit; + properties:SitesGroups + type:string; +} + interface Page { count: number; limit: number; @@ -37,7 +44,7 @@ interface Page { } interface PaginatedSitesGroup extends Page{ - items: SitesGroups[]; + items: SitesGroupsExtended[]; } enum columnNameSiteGroup { @@ -53,6 +60,13 @@ interface ColName { description?: string, } + +interface CustomGeoJson { + type: "FeatureCollection"; + features: SitesGroupsExtended[]; +} + + @Component({ selector: "monitoring-sitesgroups", templateUrl: "./monitoring-sitesgroups.component.html", @@ -87,7 +101,10 @@ export class MonitoringSitesGroupsComponent implements OnInit { // Est ce qu'un simple boolean ne convient pas ? displayFilter:boolean = false; - sitesGroups: GeoJSON; + // sitesGroups: GeoJSON; + + sitesGroups:CustomGeoJson; + // sitesGroups: any; constructor(private _sites_service: SitesService) {} ngOnInit() { @@ -102,8 +119,15 @@ export class MonitoringSitesGroupsComponent implements OnInit { this.page = {count: data.count, limit: data.limit, offset: data.offset - 1} this.sitesGroups = { features: data.items.map((group) => { - group["type"] = "Feature"; - return group; + let { + geometry, + properties, + ...others + } = group; + let result = {"geometry":geometry,"properties":properties,"type":"Feature"} + console.log("result",result) + console.log(group) + return result; }), type: "FeatureCollection", }; @@ -115,7 +139,7 @@ export class MonitoringSitesGroupsComponent implements OnInit { this.rows = this.dataTable; console.log("rows", this.rows); console.log("columns", this.columns); - this.groupSiteId = this.sitesGroups.features[0].id; + this.groupSiteId = this.sitesGroups.features[0].properties.id_sites_group; console.log("this.groupSiteId", this.groupSiteId); this.initObjectsStatus(); }); @@ -131,19 +155,20 @@ export class MonitoringSitesGroupsComponent implements OnInit { let { comments, data, - geometry, + // geometry, uuid_sites_group, - type, + // type, id_sites_group, sites_group_description, ...dataTable - } = groupSite; + } = groupSite.properties; return dataTable; }); // console.log(this.dataTable) } colsTable() { + console.log(this.dataTable) const arr = Object.keys(this.dataTable[0]); console.log("arr", arr); const allColName: ColName[] = [] @@ -166,7 +191,7 @@ export class MonitoringSitesGroupsComponent implements OnInit { objectsStatus["sites_groups"] = this.sitesGroups.features.map( (groupSite) => { return { - id: groupSite.id, + id: groupSite.properties.id_sites_group, selected: false, visible: true, current: false, @@ -182,12 +207,12 @@ export class MonitoringSitesGroupsComponent implements OnInit { this.sitesGroups.features.forEach((f) => { // determination du site courrant let cur = false; - if (f.id == this.groupSiteId) { + if (f.properties.id_sites_group == this.groupSiteId) { cur = true; } objectsStatus["sites_groups"].push({ - id: f.id, + id: f.properties.id_sites_group, selected: false, visible: true, current: cur, @@ -207,8 +232,8 @@ export class MonitoringSitesGroupsComponent implements OnInit { console.log("this.table", this.table); console.log(this.table._internalRows); - console.log("selected[0].id", selected[0].id); - const id = selected[0].id; + console.log("selected[0].id", selected[0].id_group_site); + const id = selected[0].id_group_site; if (!this.rowStatus) { return; From f10e20193b7dd8e2df4d8ccfa24add34dbba56b3 Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Tue, 17 Jan 2023 23:53:00 +0100 Subject: [PATCH 09/44] refactor: site component with site-service add function to site.services.ts [Refs ticket]: #4 --- .../monitoring-sitesgroups.component.ts | 38 ++--------- frontend/app/services/sites.service.ts | 64 +++++++++++++++++++ 2 files changed, 69 insertions(+), 33 deletions(-) diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 4dbeb24e3..ca62fd568 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -116,29 +116,17 @@ export class MonitoringSitesGroupsComponent implements OnInit { this._sites_service .getSitesGroups(offset, LIMIT, params) .subscribe((data: PaginatedSitesGroup) => { + // console.log(data) this.page = {count: data.count, limit: data.limit, offset: data.offset - 1} - this.sitesGroups = { - features: data.items.map((group) => { - let { - geometry, - properties, - ...others - } = group; - let result = {"geometry":geometry,"properties":properties,"type":"Feature"} - console.log("result",result) - console.log(group) - return result; - }), - type: "FeatureCollection", - }; + this.sitesGroups = this._sites_service.setFormatToGeoJson(data) // console.log(this.sitesGroups); - this.getDataTable(); + this.dataTable = this._sites_service.getDataTable(this.sitesGroups); this.listAllColName = this.colsTable(); // console.log(this.listAllColName) this.columns = this.listAllColName; this.rows = this.dataTable; - console.log("rows", this.rows); - console.log("columns", this.columns); + // console.log("rows", this.rows); + // console.log("columns", this.columns); this.groupSiteId = this.sitesGroups.features[0].properties.id_sites_group; console.log("this.groupSiteId", this.groupSiteId); this.initObjectsStatus(); @@ -150,22 +138,6 @@ export class MonitoringSitesGroupsComponent implements OnInit { this.getSites(e.offset + 1, this.filters) } - getDataTable() { - this.dataTable = this.sitesGroups.features.map((groupSite) => { - let { - comments, - data, - // geometry, - uuid_sites_group, - // type, - id_sites_group, - sites_group_description, - ...dataTable - } = groupSite.properties; - return dataTable; - }); - // console.log(this.dataTable) - } colsTable() { console.log(this.dataTable) diff --git a/frontend/app/services/sites.service.ts b/frontend/app/services/sites.service.ts index 4a1cd0a60..f258a7773 100644 --- a/frontend/app/services/sites.service.ts +++ b/frontend/app/services/sites.service.ts @@ -3,7 +3,39 @@ import { Injectable } from "@angular/core"; import { CacheService } from "./cache.service"; import { ConfigService } from "./config.service"; import { HttpClient } from "@angular/common/http"; +import { GeoJSON } from "leaflet"; +interface SitesGroups{ + comments?: string; + data?: any; + // geometry: any; + id_sites_group: number; + nb_sites: number; + nb_visits: number; + sites_group_code: string; + sites_group_description?: string; + sites_group_name: string; + uuid_sites_group: string; +} + +interface SitesGroupsExtended extends Omit { + // properties:Omit; + properties:SitesGroups + type:string; +} +interface Page { + count: number; + limit: number; + offset: number; +} + +interface PaginatedSitesGroup extends Page{ + items: SitesGroupsExtended[]; +} +interface CustomGeoJson { + type: "FeatureCollection"; + features: SitesGroupsExtended[]; +} @Injectable() export class SitesService { @@ -14,4 +46,36 @@ export class SitesService { getSitesGroups(offset=1, limit=10, params={}) { return this._cacheService.request("get", `sites_groups`, {queryParams: {offset, limit, ...params}}); } + + setFormatToGeoJson(data:PaginatedSitesGroup):CustomGeoJson{ + return { + features: data.items.map((group) => { + let { + geometry, + properties, + ..._ + } = group; + let result = {"geometry":geometry,"properties":properties,"type":"Feature"} + console.log("result",result) + console.log(group) + return result; + }), + type: "FeatureCollection", + }; + } + + getDataTable(data:CustomGeoJson) { + return data.features.map((groupSite) => { + let { + comments, + data, + uuid_sites_group, + id_sites_group, + sites_group_description, + ...dataTable + } = groupSite.properties; + return dataTable; + }); + } + } From acf9ff2aa7d792bcf34cd2e1b0eed806155940ea Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Wed, 18 Jan 2023 17:11:32 +0100 Subject: [PATCH 10/44] refactor: create datatable component and service Separate of concern for all about table (service and component) and all about sites (service and component) reviewed_by: andriacap [Refs ticket]: #3 --- .../monitoring-datatable-g.component.css | 48 +++ .../monitoring-datatable-g.component.html | 109 ++++++ .../monitoring-datatable-g.component.spec.ts | 25 ++ .../monitoring-datatable-g.component.ts | 208 ++++++++++++ .../monitoring-sitesgroups.component.html | 121 ++----- .../monitoring-sitesgroups.component.ts | 314 +----------------- frontend/app/gnModule.module.ts | 5 + frontend/app/services/data-table.service.ts | 104 ++++++ 8 files changed, 540 insertions(+), 394 deletions(-) create mode 100644 frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.css create mode 100644 frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html create mode 100644 frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.spec.ts create mode 100644 frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts create mode 100644 frontend/app/services/data-table.service.ts diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.css b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.css new file mode 100644 index 000000000..6017b44ab --- /dev/null +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.css @@ -0,0 +1,48 @@ +.cell-link { + cursor: pointer; +} + +:host::ng-deep .datatable-body-row.active .datatable-row-group { + background-color: rgb(117, 227, 118) !important; +} + +.link:hover { + background-color: rgba(0, 0, 0, 0.2) !important; + transition: background-color 0.5; +} + +.link { + display: inline; + transition: background-color 0.5s; + border-radius: 5px; +} + +.header-filter-span > input { + width: 100%; +} + +.header-sort-span { + /* width: 100%; */ + cursor: pointer; + text-overflow: ellipsis; + overflow: hidden; + white-space:nowrap +} + + +.header-sort-span:hover { + background-color: rgb(245, 245, 245); +} + +.icon-sort { + font-size: 1.2em; + float: right; +} + +:host::ng-deep .sort-btn { + display: none !important; +} + +.custom-dt { + box-shadow: none !important; +} diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html new file mode 100644 index 000000000..d0df6a19f --- /dev/null +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html @@ -0,0 +1,109 @@ + +
+ + +
+ + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + help + {{ column.name }} +
+
+ +
+
+
+ diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.spec.ts b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.spec.ts new file mode 100644 index 000000000..deaea12fe --- /dev/null +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MonitoringDatatableComponent } from './monitoring-datatable-g.component'; + +describe('MonitoringDatatableComponent', () => { + let component: MonitoringDatatableComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MonitoringDatatableComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MonitoringDatatableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts new file mode 100644 index 000000000..0986dbf0f --- /dev/null +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts @@ -0,0 +1,208 @@ +import { DatatableComponent } from "@swimlane/ngx-datatable"; +import { + Component, + OnInit, + Input, + Output, + EventEmitter, + ViewChild, + SimpleChanges, + TemplateRef, +} from "@angular/core"; +import { Router } from "@angular/router"; +import { MonitoringObjectService } from "./../../services/monitoring-object.service"; +import { Subject } from "rxjs"; +import { catchError, map, tap, take, debounceTime } from "rxjs/operators"; +import { DataTableService } from "../../services/data-table.service"; + +interface ColName { + name: string, + prop: string, + description?: string, +} + +interface Page { + count: number; + limit: number; + offset: number; +} + +interface ItemObjectTable { + id:number|null; + selected:boolean; + visible:boolean; + current:boolean; + } + type ItemsObjectTable = { [key: string]: ItemObjectTable } + + +@Component({ + selector: "pnx-monitoring-datatable-g", + templateUrl: "./monitoring-datatable-g.component.html", + styleUrls: ["./monitoring-datatable-g.component.css"], +}) +export class MonitoringDatatableGComponent implements OnInit { + @Input() rows; + @Input() colsname:ColName[]; + @Input() page: Page = {count: 0, limit: 0, offset: 0}; ; + @Input() obj; + + @Input() rowStatus: Array; + @Output() rowStatusChange = new EventEmitter(); + + @Output() bEditChanged = new EventEmitter(); + + @Input() currentUser; + + @Output() onSort = new EventEmitter(); + @Output() onFilter= new EventEmitter(); + @Output() onSetPage= new EventEmitter(); + + private filterSubject: Subject = new Subject(); + private subscription: any; + displayFilter:boolean = false; + objectsStatus:ItemsObjectTable; + + columns; + row_save; + selected = []; + filters = {}; + customColumnComparator; + + @ViewChild(DatatableComponent) table: DatatableComponent; + @ViewChild("actionsTemplate") actionsTemplate: TemplateRef; + @ViewChild("hdrTpl") hdrTpl: TemplateRef; + + constructor(private _dataTableService: DataTableService) {} + + ngOnInit() { + console.log('DataTableComponent colname',this.colsname) + console.log('DataTableComponent rows',this.rows) + // console.log('DataTableComponent obj',this.obj) + this.initDatatable(); + } + + initDatatable() { + console.log("Inside initDatatable") + console.log("this.rows",this.rows) + this.filters = {}; + this.filterSubject.pipe(debounceTime(500)).subscribe(() => { + this.filter(); + }); + } + + + onSortEvent($event) { + console.log("onSortEvent, $event",$event) + this.filters = {...this.filters, sort: $event.column.prop, sort_dir: $event.newValue} + console.log("onSortEvent, this.filters", this.filters) + this.onSort.emit(this.filters) + } + + setPage($event) { + this.onSetPage.emit($event) + // this.getSites(e.offset + 1, this.filters) + } + + filterInput($event) { + console.log("filterInput, $event",$event) + this.filterSubject.next(); + } + + // sort() {} + + filter(bInitFilter = false) { + // filter all + console.log("Inside DataTable-G , filter()", this.filters) + const oldFilters = this.filters + this.filters = Object.keys(oldFilters).reduce(function(r, e) { + if (![undefined, "", null].includes(oldFilters[e])) r[e] = oldFilters[e] + return r; + }, {}) + this.onFilter.emit(this.filters) + } + + onSelectEvent({ selected }) { + console.log("Select Row", selected, this.selected); + console.log("this.table", this.table); + console.log(this.table._internalRows); + console.log("selected[0]", selected[0]); + console.log("selected[0].id", selected[0].id_group_site); + const id = selected[0].id_group_site; + + if (!this.rowStatus) { + return; + } + console.log("this.rowStatus after check rowStatus", this.rowStatus); + + this.rowStatus.forEach((status) => { + const bCond = status.id === id; + status["selected"] = bCond && !status["selected"]; + }); + + this.setSelected(); + this.rowStatusChange.emit(this.rowStatus); + console.log("after click rowStatus", this.rowStatus); + console.log("after click selected", this.selected); + console.log("after click table", this.table); + } + + setSelected() { + // this.table._internalRows permet d'avoir les ligne triées et d'avoir les bons index + + if (!this.rowStatus) { + return; + } + + const status_selected = this.rowStatus.find((status) => status.selected); + if (!status_selected) { + return; + } + + const index_row_selected = this.table._internalRows.findIndex( + (row) => row.id === status_selected.id + ); + if (index_row_selected === -1) { + return; + } + + this.selected = [this.table._internalRows[index_row_selected]]; + this.table.offset = Math.floor(index_row_selected / this.table._limit); + } + + ngOnDestroy() { + this.filterSubject.unsubscribe(); + } + + // tooltip(column) { + // return this.child0.template.fieldDefinitions[column.prop] + // ? column.name + " : " + this.child0.template.fieldDefinitions[column.prop] + // : column.name; + // } + + + ngOnChanges(changes: SimpleChanges) { + console.log("inside ngOnChanges"); + console.log("changes",changes) + if (changes['rows'] && this.rows) { + this.columns = this._dataTableService.colsTable(this.colsname,this.rows); + } + + if (changes['obj'] && this.obj) { + this.objectsStatus,this.rowStatus=this._dataTableService.initObjectsStatus(this.obj,"sites_groups") + } + for (const propName of Object.keys(changes)) { + const chng = changes[propName]; + const cur = chng.currentValue; + const pre = chng.currentValue; + switch (propName) { + case "rowStatus": + this.setSelected(); + break + } + } + } + navigateToAddChildren(_,rowId){ + console.log("Inside navigateToAddChildren:",rowId) + } +} diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index b42894a17..c2ab7d6c2 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -12,103 +12,28 @@ -
- - - - +
- - - - - - - - - - - - - - - - - - -
- - - help - {{ column.name }} -
-
- -
-
- \ No newline at end of file + + \ No newline at end of file diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index ca62fd568..28d967f4c 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -14,6 +14,7 @@ import { DatatableComponent } from "@swimlane/ngx-datatable"; import { Subject } from "rxjs"; import {debounceTime } from "rxjs/operators"; import { Feature, FeatureCollection } from "geojson"; +import { DataTableService } from "../../services/data-table.service"; const LIMIT = 10 interface SitesGroups{ @@ -54,338 +55,59 @@ enum columnNameSiteGroup { sites_group_name = "Nom", } -interface ColName { - name: string, - prop: string, - description?: string, -} - - interface CustomGeoJson { type: "FeatureCollection"; features: SitesGroupsExtended[]; } -@Component({ + + @Component({ selector: "monitoring-sitesgroups", templateUrl: "./monitoring-sitesgroups.component.html", styleUrls: ["./monitoring-sitesgroups.component.css"], }) export class MonitoringSitesGroupsComponent implements OnInit { @ViewChild(DatatableComponent) table: DatatableComponent; - rowStatus: Array; - // @Input() rowStatus: Array; - @Output() rowStatusChange = new EventEmitter(); - @Output() bEditChanged = new EventEmitter(); - objectsStatus; - groupSiteId; + @Input() page: Page = {count: 0, limit: 0, offset: 0}; + @Input() dataTable; + @Input() sitesGroups:CustomGeoJson; + @Input() columnNameSiteGroup: typeof columnNameSiteGroup = columnNameSiteGroup; - private filterSubject: Subject = new Subject(); - selected = []; + filters = {}; - row_save; - - public page: Page = {count: 0, limit: 0, offset: 0}; - listAllColName: ColName[] = []; - dataTable; - rows; - columns; - - // child0 = { - // "config":{ - // "display_filter":false - // } - // } - - // Est ce qu'un simple boolean ne convient pas ? - displayFilter:boolean = false; - // sitesGroups: GeoJSON; - - sitesGroups:CustomGeoJson; - // sitesGroups: any; - - constructor(private _sites_service: SitesService) {} + constructor(private _sites_service: SitesService, private _dataTableService: DataTableService) {} ngOnInit() { this.getSites() - this.initDatatable(); } getSites(offset=1, params={}) { this._sites_service .getSitesGroups(offset, LIMIT, params) .subscribe((data: PaginatedSitesGroup) => { - // console.log(data) this.page = {count: data.count, limit: data.limit, offset: data.offset - 1} this.sitesGroups = this._sites_service.setFormatToGeoJson(data) - // console.log(this.sitesGroups); this.dataTable = this._sites_service.getDataTable(this.sitesGroups); - this.listAllColName = this.colsTable(); - // console.log(this.listAllColName) - this.columns = this.listAllColName; - this.rows = this.dataTable; - // console.log("rows", this.rows); - // console.log("columns", this.columns); - this.groupSiteId = this.sitesGroups.features[0].properties.id_sites_group; - console.log("this.groupSiteId", this.groupSiteId); - this.initObjectsStatus(); }); } - setPage(e) { - this.getSites(e.offset + 1, this.filters) + setPage($event) { + console.log('setPage Sitesgroups Components') + this.getSites($event.offset + 1, this.filters) } - - colsTable() { - console.log(this.dataTable) - const arr = Object.keys(this.dataTable[0]); - console.log("arr", arr); - const allColName: ColName[] = [] - arr.forEach((element) => { - allColName.push({ - name: - element in ["id", "id_group_site"] - ? element - : columnNameSiteGroup[element], - prop: element, - description: undefined - }); - }); - return allColName; - } - - initObjectsStatus() { - const objectsStatus = {}; - // for (const childrenType of Object.keys(this.obj.children)) { - objectsStatus["sites_groups"] = this.sitesGroups.features.map( - (groupSite) => { - return { - id: groupSite.properties.id_sites_group, - selected: false, - visible: true, - current: false, - }; - } - ); - console.log("objectsStatus", objectsStatus); - // } - - // init site status - if (this.groupSiteId) { - objectsStatus["sites_groups"] = []; - this.sitesGroups.features.forEach((f) => { - // determination du site courrant - let cur = false; - if (f.properties.id_sites_group == this.groupSiteId) { - cur = true; - } - - objectsStatus["sites_groups"].push({ - id: f.properties.id_sites_group, - selected: false, - visible: true, - current: cur, - }); - }); - } - - this.objectsStatus = objectsStatus; - console.log("objectsStatus after init", objectsStatus); - this.rowStatus = this.objectsStatus["sites_groups"]; - } - - // ICI le select renvoyé correspond directement aux valeurs de la ligne sélectionné et non à l'event - // permet de simplifier la fonction et pas besoin de check si l'event est un "click" ou non - onSelect({ selected }) { - console.log("Select Row", selected, this.selected); - console.log("this.table", this.table); - console.log(this.table._internalRows); - - console.log("selected[0].id", selected[0].id_group_site); - const id = selected[0].id_group_site; - - if (!this.rowStatus) { - return; - } - console.log("this.rowStatus after check rowStatus", this.rowStatus); - - this.rowStatus.forEach((status) => { - const bCond = status.id === id; - status["selected"] = bCond && !status["selected"]; - }); - - this.setSelected(); - this.rowStatusChange.emit(this.rowStatus); - console.log("after click rowStatus", this.rowStatus); - console.log("after click selected", this.selected); - console.log("after click table", this.table); - } - - setSelected() { - // this.table._internalRows permet d'avoir les ligne triées et d'avoir les bons index - console.log("Inside setSelected", this.rowStatus); - if (!this.rowStatus) { - return; - } - - const status_selected = this.rowStatus.find((status) => status.selected); - if (!status_selected) { - return; - } - - const index_row_selected = this.table._internalRows.findIndex( - (row) => row.id === status_selected.id - ); - if (index_row_selected === -1) { - return; - } - - this.selected = [this.table._internalRows[index_row_selected]]; - this.table.offset = Math.floor(index_row_selected / this.table._limit); - } - - // Pour l'instant fonction non active - ngOnChanges(changes: SimpleChanges) { - console.log("inside ngOnChanges"); - for (const propName of Object.keys(changes)) { - const chng = changes[propName]; - const cur = chng.currentValue; - const pre = chng.currentValue; - switch (propName) { - case "rowStatus": - this.setSelected(); - break; - // case "child0": - // this.customColumnComparator = this.customColumnComparator_(); - // break; - } - } - } - - // TEST - // onSelect({ selected }) { - // console.log('Select Event', selected, this.selected); - // } - - // onActivate(event) { - // console.log("Activate Event", event); - // } - - // if (!this.rowStatus) { - // return; - // } - - ////////////////////////////////////// - // NON utilisé car le databinding (selected)=onSelect($event) suffit par rapport au but recherché - ///////////////////////////////////////////////// - // onRowClick(event) { - // console.log("inside onRowClick- event",event) - // if (!(event && event.type === "click")) { - // return; - // } - // console.log("inside onRowClick- event.row",event.row) - // const id = event.row && event.row.id; - - // if (!this.rowStatus) { - // return; - // } - - // this.rowStatus.forEach((status) => { - // const bCond = status.id === id; - // status["selected"] = bCond && !status["selected"]; - // }); - - // this.setSelected(); - // this.rowStatusChange.emit(this.rowStatus); - // } - - ////////////////////////////////////: - // WIP : fonctions liés à des classes basées sur ce qui se faisait anciennement avec le module code en parent de tout - // A l'adapter pour coller avec l'architecture actuelle - /////////////////////// - - initDatatable() { - console.log("Inside initDatatable") - this.filters = {}; - this.filterSubject.pipe(debounceTime(500)).subscribe(() => { - this.filter(); - }); - - // this.customColumnComparator = this.customColumnComparator_(); - this.row_save = this.rows.map((e) => e); - // on declenche les filtres (si filtre par defaut) - setTimeout(() => { - this.filter(true); - }, 500); - } - - filterInput($event) { - this.filterSubject.next(); - } - - onSort($event) { - this.filters = {...this.filters, sort: $event.column.prop, sort_dir: $event.newValue} + onSortEvent(filters) { + console.log("onSortEvent sitegroups component, filters",filters) + this.filters = filters this.getSites(1, this.filters) } - filter(bInitFilter = false) { - // filter all - const oldFilters = this.filters - this.filters = Object.keys(oldFilters).reduce(function(r, e) { - if (![undefined, "", null].includes(oldFilters[e])) r[e] = oldFilters[e] - return r; - }, {}) - - //offset = 1 + onFilterEvent(filters){ + console.log("onFilterEvent sitegroups component, filters",filters) + this.filters = filters this.getSites(1, this.filters) - // let bChange = false; - // const temp = this.row_save.filter((row, index) => { - // let bCondVisible = true; - // for (const key of Object.keys(this.filters)) { - // let val = this.filters[key]; - // if ([null, undefined].includes(val)) { - // continue; - // } - // val = String(val).toLowerCase(); - // const vals = val.split(" "); - // for (const v of vals) { - // bCondVisible = - // bCondVisible && (String(row[key]) || "").toLowerCase().includes(v); - // } - // } - - // if (!this.rowStatus) { - // return bCondVisible; - // } - // bChange = bChange || bCondVisible !== this.rowStatus[index].visible; - // this.rowStatus[index]["visible"] = bCondVisible; - // this.rowStatus[index]["selected"] = - // this.rowStatus[index]["selected"] && bCondVisible; - // return bCondVisible; - //}); - - // if (bChange || bInitFilter) { - // this.rowStatusChange.emit(this.rowStatus); - // } - // // update the rows - // this.rows = temp; - // // Whenever the filter changes, always go back to the first page - // this.table.offset = 0; - // this.setSelected(); } -// TODO: TO REPLACE WITH EFFECTIVE FUNCTION -navigateToDetail(row){ - console.log("Inside navigateToDetail on eye icon",row) -} - -navigateToAddChildren(_,rowId){ - console.log("Inside navigateToAddChildren:",rowId) -} - - - } diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index 6e0253846..cc070b85f 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -25,6 +25,8 @@ import { MonitoringFormComponent } from "./components/monitoring-form/monitoring import { MonitoringListComponent } from "./components/monitoring-lists/monitoring-lists.component"; import { MonitoringPropertiesComponent } from "./components/monitoring-properties/monitoring-properties.component"; import { MonitoringDatatableComponent } from "./components/monitoring-datatable/monitoring-datatable.component"; +import { MonitoringDatatableGComponent } from "./components/monitoring-datatable-g/monitoring-datatable-g.component"; + import { MatSlideToggleModule } from "@angular/material/slide-toggle"; import { MatFormFieldModule } from "@angular/material/form-field"; @@ -33,6 +35,7 @@ import { MatSelectModule } from "@angular/material/select"; import { MatInputModule } from "@angular/material/input"; import { MonitoringSitesGroupsComponent } from "./components/monitoring-sitesgroups/monitoring-sitesgroups.component"; import { SitesService } from "./services/sites.service"; +import { DataTableService } from "./services/data-table.service"; // my module routing const routes: Routes = [ @@ -73,6 +76,7 @@ const routes: Routes = [ MonitoringPropertiesComponent, MonitoringDatatableComponent, MonitoringSitesGroupsComponent, + MonitoringDatatableGComponent ], imports: [ GN2CommonModule, @@ -97,6 +101,7 @@ const routes: Routes = [ ConfigService, MonitoringObjectService, SitesService, + DataTableService ], bootstrap: [ModulesComponent], schemas: [ diff --git a/frontend/app/services/data-table.service.ts b/frontend/app/services/data-table.service.ts new file mode 100644 index 000000000..44b6a4c39 --- /dev/null +++ b/frontend/app/services/data-table.service.ts @@ -0,0 +1,104 @@ +import { Injectable } from "@angular/core"; +import { Observable} from "rxjs"; + + +interface Page { + count: number; + limit: number; + offset: number; +} + +interface ColName { + name: string, + prop: string, + description?: string, +} + +interface ItemObjectTable { + id:number|null; + selected:boolean; + visible:boolean; + current:boolean; + } + +type ItemsObjectTable = { [key: string]: ItemObjectTable } + +@Injectable() +export class DataTableService { + +obj:ItemsObjectTable; +objectsStatus:ItemsObjectTable; +rowStatus:ItemObjectTable; +idObj:number; + +public page: Page = {count: 0, limit: 0, offset: 0}; + constructor( + ) {} + + + setPaginationConfig(count:number=0,limit:number=0, offset:number=0):Page{ + return {"count":count,"limit":limit,"offset":offset} + } +// setPage(e){ +// this.obj +// } + +colsTable(colName,dataTable):ColName[] { + const arr = Object.keys(dataTable[0]); + const allColName: ColName[] = [] + arr.forEach((element) => { + allColName.push({ + name: + element in ["id", "id_group_site"] + ? element + : colName[element], + prop: element, + description: undefined + }); + }); + return allColName; +} + +initObjectsStatus(obj,key) { + const objectsStatus = {}; + // for (const childrenType of Object.keys(this.obj.children)) { + objectsStatus[key] = obj.features.map( + (groupSite) => { + return { + id: groupSite.properties.id_sites_group, + selected: false, + visible: true, + current: false, + }; + } + ); + console.log("objectsStatus", objectsStatus); + // } + + // init site status + if (this.idObj) { + objectsStatus[key] = []; + obj.features.forEach((f) => { + // determination du site courrant + let cur = false; + if (f.properties.id_sites_group == this.idObj) { + cur = true; + } + + objectsStatus[key].push({ + id: f.properties.id_sites_group, + selected: false, + visible: true, + current: cur, + }); + }); + } + + this.objectsStatus = objectsStatus; + this.rowStatus = this.objectsStatus[key]; + console.log("datatable service",this.rowStatus) + return [this.objectsStatus ,this.rowStatus] +} + + +} From 868348c28bfd7d40cb3f3dd3ce2a386470526910 Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Thu, 19 Jan 2023 10:12:26 +0100 Subject: [PATCH 11/44] fix: change offset to page change offset name to page for paginated Reviewed-by: andriacap [Refs ticket]: #4 --- .../monitoring-datatable-g.component.html | 2 +- .../monitoring-sitesgroups.component.ts | 12 ++++++------ frontend/app/services/data-table.service.ts | 8 ++++---- frontend/app/services/sites.service.ts | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html index d0df6a19f..df467f8d6 100644 --- a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html @@ -33,7 +33,7 @@ [rowHeight]="40" [externalPaging]="true" [count]="page.count" - [offset]="page.offset" + [offset]="page.page" [limit]="page.limit" [rows]="rows" [columns]="columns" diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 28d967f4c..aaa2432fa 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -41,7 +41,7 @@ interface SitesGroupsExtended extends Omit { interface Page { count: number; limit: number; - offset: number; + page: number; } interface PaginatedSitesGroup extends Page{ @@ -69,7 +69,7 @@ interface CustomGeoJson { }) export class MonitoringSitesGroupsComponent implements OnInit { @ViewChild(DatatableComponent) table: DatatableComponent; - @Input() page: Page = {count: 0, limit: 0, offset: 0}; + @Input() page: Page = {count: 0, limit: 0, page: 0}; @Input() dataTable; @Input() sitesGroups:CustomGeoJson; @Input() columnNameSiteGroup: typeof columnNameSiteGroup = columnNameSiteGroup; @@ -82,11 +82,11 @@ export class MonitoringSitesGroupsComponent implements OnInit { this.getSites() } - getSites(offset=1, params={}) { + getSites(page=1, params={}) { this._sites_service - .getSitesGroups(offset, LIMIT, params) + .getSitesGroups(page, LIMIT, params) .subscribe((data: PaginatedSitesGroup) => { - this.page = {count: data.count, limit: data.limit, offset: data.offset - 1} + this.page = {count: data.count, limit: data.limit, page: data.page - 1} this.sitesGroups = this._sites_service.setFormatToGeoJson(data) this.dataTable = this._sites_service.getDataTable(this.sitesGroups); }); @@ -95,7 +95,7 @@ export class MonitoringSitesGroupsComponent implements OnInit { setPage($event) { console.log('setPage Sitesgroups Components') - this.getSites($event.offset + 1, this.filters) + this.getSites($event.page + 1, this.filters) } onSortEvent(filters) { diff --git a/frontend/app/services/data-table.service.ts b/frontend/app/services/data-table.service.ts index 44b6a4c39..88a662264 100644 --- a/frontend/app/services/data-table.service.ts +++ b/frontend/app/services/data-table.service.ts @@ -5,7 +5,7 @@ import { Observable} from "rxjs"; interface Page { count: number; limit: number; - offset: number; + page: number; } interface ColName { @@ -31,13 +31,13 @@ objectsStatus:ItemsObjectTable; rowStatus:ItemObjectTable; idObj:number; -public page: Page = {count: 0, limit: 0, offset: 0}; +public page: Page = {count: 0, limit: 0, page: 0}; constructor( ) {} - setPaginationConfig(count:number=0,limit:number=0, offset:number=0):Page{ - return {"count":count,"limit":limit,"offset":offset} + setPaginationConfig(count:number=0,limit:number=0, page:number=0):Page{ + return {"count":count,"limit":limit,"page":page} } // setPage(e){ // this.obj diff --git a/frontend/app/services/sites.service.ts b/frontend/app/services/sites.service.ts index f258a7773..1b6ec315b 100644 --- a/frontend/app/services/sites.service.ts +++ b/frontend/app/services/sites.service.ts @@ -26,7 +26,7 @@ interface SitesGroupsExtended extends Omit { interface Page { count: number; limit: number; - offset: number; + page: number; } interface PaginatedSitesGroup extends Page{ @@ -43,8 +43,8 @@ export class SitesService { private _cacheService: CacheService ) {} - getSitesGroups(offset=1, limit=10, params={}) { - return this._cacheService.request("get", `sites_groups`, {queryParams: {offset, limit, ...params}}); + getSitesGroups(page=1, limit=10, params={}) { + return this._cacheService.request("get", `sites_groups`, {queryParams: {page, limit, ...params}}); } setFormatToGeoJson(data:PaginatedSitesGroup):CustomGeoJson{ From 7b6340a5402b1c4d44a4724c027aa73c8484469e Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Thu, 19 Jan 2023 12:35:39 +0100 Subject: [PATCH 12/44] merge: merge interface and type merge site_group.service.ts delete site.service.ts add interfaces re arrange code from branch front-site-interface Reviewed-by: andriacap [Refs ticket]: #4 --- .../b53bafb13ce8_create_bib_type_site.py | 26 +++- .../monitoring/schemas.py | 6 +- frontend/app/class/monitoring-site.ts | 54 +++++++ frontend/app/class/monitoring-sites-group.ts | 36 +++++ .../monitoring-datatable-g.component.html | 105 ++++++++------ .../monitoring-datatable-g.component.ts | 105 +++++++------- .../monitoring-sitesgroups.component.html | 56 +++----- .../monitoring-sitesgroups.component.ts | 115 +++++---------- frontend/app/gnModule.module.ts | 6 +- frontend/app/interfaces/column.ts | 5 + frontend/app/interfaces/geom.ts | 49 +++++++ frontend/app/interfaces/page.ts | 9 ++ frontend/app/services/cache.service.ts | 10 +- frontend/app/services/data-table.service.ts | 135 +++++++----------- frontend/app/services/sites_group.service.ts | 33 +++++ 15 files changed, 435 insertions(+), 315 deletions(-) create mode 100644 frontend/app/class/monitoring-site.ts create mode 100644 frontend/app/class/monitoring-sites-group.ts create mode 100644 frontend/app/interfaces/column.ts create mode 100644 frontend/app/interfaces/geom.ts create mode 100644 frontend/app/interfaces/page.ts create mode 100644 frontend/app/services/sites_group.service.ts diff --git a/backend/gn_module_monitoring/migrations/b53bafb13ce8_create_bib_type_site.py b/backend/gn_module_monitoring/migrations/b53bafb13ce8_create_bib_type_site.py index de4d92d60..b079edf9e 100644 --- a/backend/gn_module_monitoring/migrations/b53bafb13ce8_create_bib_type_site.py +++ b/backend/gn_module_monitoring/migrations/b53bafb13ce8_create_bib_type_site.py @@ -36,11 +36,27 @@ def upgrade(): schema=monitorings_schema, ) - op.create_check_constraint( - "ck_bib_type_site_id_nomenclature", - "bib_type_site", - f"{nomenclature_schema}.check_nomenclature_type_by_mnemonique(id_nomenclature,'TYPE_SITE')", - schema=monitorings_schema) + # FIXME: if sqlalchemy >= 1.4.32, it should work with postgresql_not_valid=True: cleaner + # op.create_check_constraint( + # "ck_bib_type_site_id_nomenclature_type_site", + # "bib_type_site", + # f"{nomenclature_schema}.check_nomenclature_type_by_mnemonique(id_nomenclature_type_site,'TYPE_SITE')", + # schema=monitorings_schema, + # postgresql_not_valid=True + # ) + statement = sa.text( + f""" + ALTER TABLE {monitorings_schema}.bib_type_site + ADD + CONSTRAINT ck_bib_type_site_id_nomenclature_type_site CHECK ( + {nomenclature_schema}.check_nomenclature_type_by_mnemonique( + id_nomenclature_type_site, 'TYPE_SITE' :: character varying + ) + ) NOT VALID + """ + ) + op.execute(statement) + def downgrade(): op.drop_table("bib_type_site", schema=monitorings_schema) diff --git a/backend/gn_module_monitoring/monitoring/schemas.py b/backend/gn_module_monitoring/monitoring/schemas.py index 59c76d13a..d42211706 100644 --- a/backend/gn_module_monitoring/monitoring/schemas.py +++ b/backend/gn_module_monitoring/monitoring/schemas.py @@ -29,10 +29,10 @@ class Meta: geometry = fields.Method("serialize_geojson", dump_only=True) - properties = fields.Method("group_properties_geojson") + # properties = fields.Method("group_properties_geojson") - def group_properties_geojson(self, obj): - return {field: getattr(obj,field) for field in self.fields.keys() if field not in ("geometry","properties")} + # def group_properties_geojson(self, obj): + # return {field: getattr(obj,field) for field in self.fields.keys() if field not in ("geometry","properties")} def serialize_geojson(self, obj): if obj.geom_geojson is not None: diff --git a/frontend/app/class/monitoring-site.ts b/frontend/app/class/monitoring-site.ts new file mode 100644 index 000000000..e3003420c --- /dev/null +++ b/frontend/app/class/monitoring-site.ts @@ -0,0 +1,54 @@ +import { ISite, JsonData } from "../interfaces/geom"; +import { GeoJSON } from "geojson"; + +export class MonitoringSite implements ISite { + altitude_max: number; + altitude_min: number; + base_site_code: string; + base_site_description?: string; + base_site_name: string; + data: JsonData; + first_use_date: string; + geometry: GeoJSON.FeatureCollection; + id_base_site: number; + id_nomenclature_type_site?: number; + last_visit?: Date; + meta_create_date: Date; + meta_update_date: Date; + nb_visits: number; + uuid_base_site: string; + + constructor( + altitude_max: number, + altitude_min: number, + base_site_code: string, + base_site_description: string, + base_site_name: string, + data: JsonData, + geometry: GeoJSON.FeatureCollection, + first_use_date: string, + id_base_site: number, + id_nomenclature_type_site: number, + last_visit: Date, + meta_create_date: Date, + meta_update_date: Date, + nb_visits: number, + uuid_base_site: string + ) { + this.altitude_max = altitude_max; + this.altitude_min = altitude_min; + this.base_site_code = base_site_code; + this.base_site_description = base_site_description; + this.base_site_name = base_site_name; + this.data = data; + this.first_use_date = first_use_date; + this.geometry = geometry; + this.id_base_site = id_base_site; + this.id_nomenclature_type_site = id_nomenclature_type_site; + this.last_visit = last_visit; + this.meta_create_date = meta_create_date; + this.meta_update_date = meta_update_date; + this.nb_visits = nb_visits; + this.uuid_base_site = uuid_base_site; + } +} diff --git a/frontend/app/class/monitoring-sites-group.ts b/frontend/app/class/monitoring-sites-group.ts new file mode 100644 index 000000000..4bd29e796 --- /dev/null +++ b/frontend/app/class/monitoring-sites-group.ts @@ -0,0 +1,36 @@ +import { ISitesGroup, JsonData } from "../interfaces/geom"; +import { GeoJSON } from "geojson"; + +export class MonitoringSitesGroup implements ISitesGroup { + id_sites_group: number; + sites_group_name: string; + sites_group_code: string; + sites_group_description: string; + geometry: GeoJSON.FeatureCollection; + data: JsonData; + nb_sites: number; + nb_visits: number; + uuid_sites_group: string; //FIXME: see if OK + + constructor( + id_sites_group: number, + sites_group_name: string, + sites_group_code: string, + sites_group_description: string, + geometry: GeoJSON.FeatureCollection, + data: JsonData, + nb_sites: number, + nb_visits: number, + uuid_sites_group: string = "" //FIXME: see if OK + ) { + this.id_sites_group = id_sites_group; + this.sites_group_name = sites_group_name; + this.sites_group_code = sites_group_code; + this.sites_group_description = sites_group_description; + this.geometry = geometry; + this.data = data; + this.nb_sites = nb_sites; + this.nb_visits = nb_visits; + this.uuid_sites_group = uuid_sites_group; + } +} diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html index df467f8d6..690217aa1 100644 --- a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html @@ -1,5 +1,5 @@ -
+
- + + + + + Ajouter un nouveau groupe de + site +
- + - - + + - - + +
- - + help - {{ column.name }} + >help + + {{ column.name }}
; @@ -55,19 +52,18 @@ export class MonitoringDatatableGComponent implements OnInit { @Input() currentUser; @Output() onSort = new EventEmitter(); - @Output() onFilter= new EventEmitter(); - @Output() onSetPage= new EventEmitter(); + @Output() onFilter = new EventEmitter(); + @Output() onSetPage = new EventEmitter(); private filterSubject: Subject = new Subject(); private subscription: any; - displayFilter:boolean = false; - objectsStatus:ItemsObjectTable; + displayFilter: boolean = false; + objectsStatus: ItemsObjectTable; columns; row_save; selected = []; filters = {}; - customColumnComparator; @ViewChild(DatatableComponent) table: DatatableComponent; @ViewChild("actionsTemplate") actionsTemplate: TemplateRef; @@ -76,52 +72,51 @@ export class MonitoringDatatableGComponent implements OnInit { constructor(private _dataTableService: DataTableService) {} ngOnInit() { - console.log('DataTableComponent colname',this.colsname) - console.log('DataTableComponent rows',this.rows) - // console.log('DataTableComponent obj',this.obj) + console.log("DataTableComponent colname", this.colsname); + console.log("DataTableComponent rows", this.rows); this.initDatatable(); } initDatatable() { - console.log("Inside initDatatable") - console.log("this.rows",this.rows) + console.log("Inside initDatatable"); + console.log("this.rows", this.rows); this.filters = {}; this.filterSubject.pipe(debounceTime(500)).subscribe(() => { this.filter(); }); } - onSortEvent($event) { - console.log("onSortEvent, $event",$event) - this.filters = {...this.filters, sort: $event.column.prop, sort_dir: $event.newValue} - console.log("onSortEvent, this.filters", this.filters) - this.onSort.emit(this.filters) + console.log("onSortEvent, $event", $event); + this.filters = { + ...this.filters, + sort: $event.column.prop, + sort_dir: $event.newValue, + }; + console.log("onSortEvent, this.filters", this.filters); + this.onSort.emit(this.filters); } setPage($event) { - this.onSetPage.emit($event) - // this.getSites(e.offset + 1, this.filters) + this.onSetPage.emit($event); } filterInput($event) { - console.log("filterInput, $event",$event) + console.log("filterInput, $event", $event); this.filterSubject.next(); } - // sort() {} - filter(bInitFilter = false) { // filter all - console.log("Inside DataTable-G , filter()", this.filters) - const oldFilters = this.filters - this.filters = Object.keys(oldFilters).reduce(function(r, e) { - if (![undefined, "", null].includes(oldFilters[e])) r[e] = oldFilters[e] + console.log("Inside DataTable-G , filter()", this.filters); + const oldFilters = this.filters; + this.filters = Object.keys(oldFilters).reduce(function (r, e) { + if (![undefined, "", null].includes(oldFilters[e])) r[e] = oldFilters[e]; return r; - }, {}) - this.onFilter.emit(this.filters) + }, {}); + this.onFilter.emit(this.filters); } - + onSelectEvent({ selected }) { console.log("Select Row", selected, this.selected); console.log("this.table", this.table); @@ -180,17 +175,23 @@ export class MonitoringDatatableGComponent implements OnInit { // : column.name; // } - ngOnChanges(changes: SimpleChanges) { console.log("inside ngOnChanges"); - console.log("changes",changes) - if (changes['rows'] && this.rows) { - this.columns = this._dataTableService.colsTable(this.colsname,this.rows); + console.log("changes", changes); + if (changes["rows"] && this.rows) { + this.columns = this._dataTableService.colsTable( + this.colsname, + this.rows[0] + ); } - if (changes['obj'] && this.obj) { - this.objectsStatus,this.rowStatus=this._dataTableService.initObjectsStatus(this.obj,"sites_groups") - } + if (changes["obj"] && this.obj) { + this.objectsStatus, + (this.rowStatus = this._dataTableService.initObjectsStatus( + this.obj, + "sites_groups" + )); + } for (const propName of Object.keys(changes)) { const chng = changes[propName]; const cur = chng.currentValue; @@ -198,11 +199,11 @@ export class MonitoringDatatableGComponent implements OnInit { switch (propName) { case "rowStatus": this.setSelected(); - break + break; } } } - navigateToAddChildren(_,rowId){ - console.log("Inside navigateToAddChildren:",rowId) + navigateToAddChildren(_, rowId) { + console.log("Inside navigateToAddChildren:", rowId); } } diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index c2ab7d6c2..41ff4cd8b 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -1,39 +1,25 @@
-
- - - -
-
- - -
+ +
- - \ No newline at end of file diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index aaa2432fa..a0dc2bed6 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -1,113 +1,62 @@ -import { - Component, - OnInit, - Input, - Output, - EventEmitter, - ViewChild, - SimpleChanges, -} from "@angular/core"; -import { SitesService } from "../../services/sites.service"; -import { GeoJSON } from "leaflet"; +import { Component, OnInit, Input } from "@angular/core"; +import { SitesGroupService } from "../../services/sites_group.service"; +import { MonitoringSitesGroup } from "../../class/monitoring-sites-group"; +import { Page, Paginated } from "../../interfaces/page"; -import { DatatableComponent } from "@swimlane/ngx-datatable"; -import { Subject } from "rxjs"; -import {debounceTime } from "rxjs/operators"; -import { Feature, FeatureCollection } from "geojson"; -import { DataTableService } from "../../services/data-table.service"; - -const LIMIT = 10 -interface SitesGroups{ - comments?: string; - data?: any; - // geometry: any; - id_sites_group: number; - nb_sites: number; - nb_visits: number; - sites_group_code: string; - sites_group_description?: string; - sites_group_name: string; - uuid_sites_group: string; -} - - - -interface SitesGroupsExtended extends Omit { - // properties:Omit; - properties:SitesGroups - type:string; -} - -interface Page { - count: number; - limit: number; - page: number; -} - -interface PaginatedSitesGroup extends Page{ - items: SitesGroupsExtended[]; -} +const LIMIT = 10; enum columnNameSiteGroup { + sites_group_name = "Nom", nb_sites = "Nb. sites", nb_visits = "Nb. visites", sites_group_code = "Code", - sites_group_name = "Nom", -} - -interface CustomGeoJson { - type: "FeatureCollection"; - features: SitesGroupsExtended[]; } - - - @Component({ +@Component({ selector: "monitoring-sitesgroups", templateUrl: "./monitoring-sitesgroups.component.html", styleUrls: ["./monitoring-sitesgroups.component.css"], }) export class MonitoringSitesGroupsComponent implements OnInit { - @ViewChild(DatatableComponent) table: DatatableComponent; - @Input() page: Page = {count: 0, limit: 0, page: 0}; - @Input() dataTable; - @Input() sitesGroups:CustomGeoJson; - @Input() columnNameSiteGroup: typeof columnNameSiteGroup = columnNameSiteGroup; + @Input() page: Page; + @Input() sitesGroups: MonitoringSitesGroup[]; + @Input() columnNameSiteGroup: typeof columnNameSiteGroup = + columnNameSiteGroup; - filters = {}; - constructor(private _sites_service: SitesService, private _dataTableService: DataTableService) {} + constructor(private _sites_group_service: SitesGroupService) {} ngOnInit() { - this.getSites() + this.getSitesGroups(); } - getSites(page=1, params={}) { - this._sites_service - .getSitesGroups(page, LIMIT, params) - .subscribe((data: PaginatedSitesGroup) => { - this.page = {count: data.count, limit: data.limit, page: data.page - 1} - this.sitesGroups = this._sites_service.setFormatToGeoJson(data) - this.dataTable = this._sites_service.getDataTable(this.sitesGroups); + getSitesGroups(page = 1, params = {}) { + this._sites_group_service + .get(page, LIMIT, params) + .subscribe((data: Paginated) => { + this.page = { + count: data.count, + limit: data.limit, + page: data.page - 1, + }; + this.sitesGroups = data.items; }); - } setPage($event) { - console.log('setPage Sitesgroups Components') - this.getSites($event.page + 1, this.filters) + console.log("setPage Sitesgroups Components"); + this.getSitesGroups($event.page + 1, this.filters); } onSortEvent(filters) { - console.log("onSortEvent sitegroups component, filters",filters) - this.filters = filters - this.getSites(1, this.filters) + console.log("onSortEvent sitegroups component, filters", filters); + this.filters = filters; + this.getSitesGroups(1, this.filters); } - onFilterEvent(filters){ - console.log("onFilterEvent sitegroups component, filters",filters) - this.filters = filters - this.getSites(1, this.filters) + onFilterEvent(filters) { + console.log("onFilterEvent sitegroups component, filters", filters); + this.filters = filters; + this.getSitesGroups(1, this.filters); } - } diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index cc070b85f..902bd7205 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -34,8 +34,8 @@ import { MatAutocompleteModule } from "@angular/material/autocomplete"; import { MatSelectModule } from "@angular/material/select"; import { MatInputModule } from "@angular/material/input"; import { MonitoringSitesGroupsComponent } from "./components/monitoring-sitesgroups/monitoring-sitesgroups.component"; -import { SitesService } from "./services/sites.service"; import { DataTableService } from "./services/data-table.service"; +import { SitesGroupService } from "./services/sites_group.service"; // my module routing const routes: Routes = [ @@ -100,8 +100,8 @@ const routes: Routes = [ DataUtilsService, ConfigService, MonitoringObjectService, - SitesService, - DataTableService + DataTableService, + SitesGroupService, ], bootstrap: [ModulesComponent], schemas: [ diff --git a/frontend/app/interfaces/column.ts b/frontend/app/interfaces/column.ts new file mode 100644 index 000000000..2f395be28 --- /dev/null +++ b/frontend/app/interfaces/column.ts @@ -0,0 +1,5 @@ +export interface Column { + name: string; + prop: string; + description?: string; +} diff --git a/frontend/app/interfaces/geom.ts b/frontend/app/interfaces/geom.ts new file mode 100644 index 000000000..3bbeb5fdb --- /dev/null +++ b/frontend/app/interfaces/geom.ts @@ -0,0 +1,49 @@ +import { GeoJSON } from "geojson"; +import { Observable } from "rxjs"; +import { Paginated } from "./page"; + +export type JsonData = { [key: string]: any }; + +export interface IGeomObject { + data: JsonData; + geometry: GeoJSON.FeatureCollection; +} + +export interface ISitesGroup extends IGeomObject { + comments?: string; + id_sites_group: number; + nb_sites: number; + nb_visits: number; + sites_group_code: string; + sites_group_description: string; + sites_group_name: string; + uuid_sites_group: string; //FIXME: see if OK +} + +export interface ISite extends IGeomObject { + altitude_max: number; + altitude_min: number; + base_site_code: string; + base_site_description?: string; + base_site_name: string; + first_use_date: string; + id_base_site: number; + id_nomenclature_type_site?: number; + last_visit?: Date; + meta_create_date: Date; + meta_update_date: Date; + nb_visits: number; + uuid_base_site: string; +} + +export interface IGeomService { + get( + limit: number, + page: number, + params: JsonData + ): Observable>; + // get_geometries(): GeoJson + // create(obj: IGeomObject) + // patch(obj: IGeomObject) + // delete(obj: IGeomObject) +} diff --git a/frontend/app/interfaces/page.ts b/frontend/app/interfaces/page.ts new file mode 100644 index 000000000..1f41f6a84 --- /dev/null +++ b/frontend/app/interfaces/page.ts @@ -0,0 +1,9 @@ +export interface Page { + count: number; + limit: number; + page: number; +} + +export interface Paginated extends Page { + items: T[]; +} diff --git a/frontend/app/services/cache.service.ts b/frontend/app/services/cache.service.ts index 876ac07f0..9fcbbc0e7 100644 --- a/frontend/app/services/cache.service.ts +++ b/frontend/app/services/cache.service.ts @@ -3,7 +3,7 @@ import { Injectable } from "@angular/core"; import { HttpClient, HttpHeaders } from "@angular/common/http"; import { Observable, of, Subject } from "rxjs"; -import { mergeMap, concatMap } from "rxjs/operators"; +import { mergeMap} from "rxjs/operators"; import { ConfigService } from "./config.service"; @@ -27,14 +27,14 @@ export class CacheService { * @param urlRelative url relative de la route * @param data post data (optionnel) */ - request( + request>( requestType: string, urlRelative: string, { postData = {}, queryParams = {} } = {} - ) { + ): Return { // verification de requestType if (!["get", "post", "patch", "delete"].includes(requestType)) { - return of(null); + throw console.error("Request must be get, post, patch or delete"); } const url_params = Object.keys(queryParams).length @@ -52,7 +52,7 @@ export class CacheService { this._config.backendModuleUrl() + "/" + urlRelative + url_params; // requete - return this._http[requestType](url, postData); + return this._http[requestType](url, postData); } /** Cache diff --git a/frontend/app/services/data-table.service.ts b/frontend/app/services/data-table.service.ts index 88a662264..0d17d5687 100644 --- a/frontend/app/services/data-table.service.ts +++ b/frontend/app/services/data-table.service.ts @@ -1,104 +1,73 @@ import { Injectable } from "@angular/core"; -import { Observable} from "rxjs"; - - -interface Page { - count: number; - limit: number; - page: number; -} - -interface ColName { - name: string, - prop: string, - description?: string, -} +import { Column } from "../interfaces/column"; interface ItemObjectTable { - id:number|null; - selected:boolean; - visible:boolean; - current:boolean; - } + id: number | null; + selected: boolean; + visible: boolean; + current: boolean; +} -type ItemsObjectTable = { [key: string]: ItemObjectTable } +type ItemsObjectTable = { [key: string]: ItemObjectTable }; @Injectable() export class DataTableService { + obj: ItemsObjectTable; + objectsStatus: ItemsObjectTable; + rowStatus: ItemObjectTable; + idObj: number; -obj:ItemsObjectTable; -objectsStatus:ItemsObjectTable; -rowStatus:ItemObjectTable; -idObj:number; - -public page: Page = {count: 0, limit: 0, page: 0}; - constructor( - ) {} + constructor() {} - - setPaginationConfig(count:number=0,limit:number=0, page:number=0):Page{ - return {"count":count,"limit":limit,"page":page} + colsTable(colName, dataTable): Column[] { + const arr = Object.keys(colName); + const allColumn: Column[] = arr + .filter((item) => Object.keys(dataTable).includes(item)) + .map((elm) => ({ + name: colName[elm], + prop: elm, + description: elm, + })); + return allColumn; } -// setPage(e){ -// this.obj -// } - -colsTable(colName,dataTable):ColName[] { - const arr = Object.keys(dataTable[0]); - const allColName: ColName[] = [] - arr.forEach((element) => { - allColName.push({ - name: - element in ["id", "id_group_site"] - ? element - : colName[element], - prop: element, - description: undefined - }); - }); - return allColName; -} -initObjectsStatus(obj,key) { - const objectsStatus = {}; - // for (const childrenType of Object.keys(this.obj.children)) { - objectsStatus[key] = obj.features.map( - (groupSite) => { + initObjectsStatus(obj, key) { + console.log("obj InitObjectStatus", obj); + const objectsStatus = {}; + // for (const childrenType of Object.keys(this.obj.children)) { + objectsStatus[key] = obj.map((groupSite) => { return { - id: groupSite.properties.id_sites_group, + id: groupSite.id_sites_group, selected: false, visible: true, current: false, }; - } - ); - console.log("objectsStatus", objectsStatus); - // } + }); + console.log("objectsStatus", objectsStatus); + // } - // init site status - if (this.idObj) { - objectsStatus[key] = []; - obj.features.forEach((f) => { - // determination du site courrant - let cur = false; - if (f.properties.id_sites_group == this.idObj) { - cur = true; - } + // init site status + if (this.idObj) { + objectsStatus[key] = []; + obj.features.forEach((f) => { + // determination du site courrant + let cur = false; + if (f.properties.id_sites_group == this.idObj) { + cur = true; + } - objectsStatus[key].push({ - id: f.properties.id_sites_group, - selected: false, - visible: true, - current: cur, + objectsStatus[key].push({ + id: f.properties.id_sites_group, + selected: false, + visible: true, + current: cur, + }); }); - }); - } - - this.objectsStatus = objectsStatus; - this.rowStatus = this.objectsStatus[key]; - console.log("datatable service",this.rowStatus) - return [this.objectsStatus ,this.rowStatus] -} + } - + this.objectsStatus = objectsStatus; + this.rowStatus = this.objectsStatus[key]; + console.log("datatable service", this.rowStatus); + return [this.objectsStatus, this.rowStatus]; + } } diff --git a/frontend/app/services/sites_group.service.ts b/frontend/app/services/sites_group.service.ts new file mode 100644 index 000000000..fd8f10b5d --- /dev/null +++ b/frontend/app/services/sites_group.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +// import { GeoJSON } from "geojson"; + +import { CacheService } from "./cache.service"; +import { IGeomService, JsonData, ISitesGroup } from "../interfaces/geom"; +import { Paginated } from "../interfaces/page"; +import { MonitoringSitesGroup } from "../class/monitoring-sites-group"; + +@Injectable() +export class SitesGroupService implements IGeomService { + constructor(private _cacheService: CacheService) {} + + get( + page: number = 1, + limit: number = 10, + params: JsonData = {} + ): Observable> { + return this._cacheService + .request>>("get", `sites_groups`, { + queryParams: { page, limit, ...params }, + }) + .pipe( + map((response: Paginated) => ({ + ...response, + items: response.items.map( + (item: ISitesGroup) => item as MonitoringSitesGroup + ), + })) + ); + } +} From 49a9bd55c589db2071dc4089aae6f2edb590fdbb Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Thu, 19 Jan 2023 18:46:45 +0100 Subject: [PATCH 13/44] feat: details properties sites groups Create properties components to display properties of sites_groups Adding route with id according to the site group selected Reviewed-by: andriacap [Refs ticket]: #4 --- frontend/app/class/monitoring-sites-group.ts | 14 +++ .../monitoring-datatable-g.component.html | 2 +- .../monitoring-datatable-g.component.ts | 5 + .../monitoring-properties-g.component.css | 33 +++++ .../monitoring-properties-g.component.html | 113 ++++++++++++++++++ .../monitoring-properties-g.component.spec.ts | 25 ++++ .../monitoring-properties-g.component.ts | 55 +++++++++ .../monitoring-sitesgroups.component.html | 25 ++-- .../monitoring-sitesgroups.component.ts | 44 +++++-- frontend/app/gnModule.module.ts | 11 +- 10 files changed, 305 insertions(+), 22 deletions(-) create mode 100644 frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.css create mode 100644 frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html create mode 100644 frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.spec.ts create mode 100644 frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts diff --git a/frontend/app/class/monitoring-sites-group.ts b/frontend/app/class/monitoring-sites-group.ts index 4bd29e796..8bed67806 100644 --- a/frontend/app/class/monitoring-sites-group.ts +++ b/frontend/app/class/monitoring-sites-group.ts @@ -1,6 +1,20 @@ import { ISitesGroup, JsonData } from "../interfaces/geom"; import { GeoJSON } from "geojson"; +export enum columnNameSiteGroup { + sites_group_name = "Nom", + nb_sites = "Nb. sites", + nb_visits = "Nb. visites", + sites_group_code = "Code", +} + +export const extendedDetailsSiteGroup = { + ...columnNameSiteGroup, + comments: "Commentaires", + sites_group_description: "Description", +}; +// export type detailsSiteGroups = columnNameSiteGroup | extendedDetailsSiteGroup + export class MonitoringSitesGroup implements ISitesGroup { id_sites_group: number; sites_group_name: string; diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html index 690217aa1..cb8d1af18 100644 --- a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html @@ -59,7 +59,7 @@ diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts index e5fa44f96..01cafd5bb 100644 --- a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts @@ -54,6 +54,7 @@ export class MonitoringDatatableGComponent implements OnInit { @Output() onSort = new EventEmitter(); @Output() onFilter = new EventEmitter(); @Output() onSetPage = new EventEmitter(); + @Output() onDetailsRow = new EventEmitter(); private filterSubject: Subject = new Subject(); private subscription: any; @@ -206,4 +207,8 @@ export class MonitoringDatatableGComponent implements OnInit { navigateToAddChildren(_, rowId) { console.log("Inside navigateToAddChildren:", rowId); } + navigateToDetail(row) { + console.log("Inside navigateToDetail:", row); + this.onDetailsRow.emit(row); + } } diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.css b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.css new file mode 100644 index 000000000..c2fc53c60 --- /dev/null +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.css @@ -0,0 +1,33 @@ +table { + font-size: small; +} + +th { + text-align: right; +} + +.key { + font-weight: bold; +} + +td { + padding-left: 20px; +} + +.small-icon { + font-size: 18px; +} + +.medias-tab { + margin: 10px; +} + +.hide-spinner { + display: none; +} + + +::ng-deep .cdk-global-overlay-wrapper, +::ng-deep .cdk-overlay-container { + z-index: 99999 !important; +} diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html new file mode 100644 index 000000000..d8701bc3b --- /dev/null +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html @@ -0,0 +1,113 @@ +
+
+ + +
+
diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.spec.ts b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.spec.ts new file mode 100644 index 000000000..dd9bf0fc3 --- /dev/null +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MonitoringPropertiesComponent } from './monitoring-properties-g.component'; + +describe('MonitoringPropertiesGComponent', () => { + let component: MonitoringPropertiesComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MonitoringPropertiesComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MonitoringPropertiesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts new file mode 100644 index 000000000..0fc3b71f4 --- /dev/null +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts @@ -0,0 +1,55 @@ +import { + Component, + OnInit, + Input, + Output, + EventEmitter, + SimpleChanges, +} from "@angular/core"; +import { FormControl } from "@angular/forms"; +import { + MonitoringSitesGroup, + extendedDetailsSiteGroup, +} from "../../class/monitoring-sites-group"; + +@Component({ + selector: "pnx-monitoring-properties-g", + templateUrl: "./monitoring-properties-g.component.html", + styleUrls: ["./monitoring-properties-g.component.css"], +}) +export class MonitoringPropertiesGComponent implements OnInit { + @Input() selectedObj: MonitoringSitesGroup; + @Input() bEdit: boolean; + @Output() bEditChange = new EventEmitter(); + + Object = Object; + + // @Input() currentUser; + infosColsSiteGroups: typeof extendedDetailsSiteGroup = + extendedDetailsSiteGroup; + color: string = "white"; + dataDetails: MonitoringSitesGroup; + + datasetForm = new FormControl(); + bUpdateSyntheseSpinner = false; + public modalReference; + + constructor() {} + + ngOnInit() { + console.log("selectedObj", this.selectedObj); + console.log("infosColsSiteGroups", this.infosColsSiteGroups); + } + + onEditClick() { + this.bEditChange.emit(true); + } + + // ngOnChanges(changes: SimpleChanges) { + // console.log("inside ngOnChanges"); + // console.log("changes", changes); + // if (changes["selectedObj"] && this.selectedObj) { + // console.log(this.selectedObj) + // } + // } +} diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index 41ff4cd8b..af259537c 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -12,14 +12,21 @@ - +
+ + +
+
+ +
diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index a0dc2bed6..47612656a 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -1,17 +1,17 @@ import { Component, OnInit, Input } from "@angular/core"; +import { LocationStrategy } from "@angular/common"; import { SitesGroupService } from "../../services/sites_group.service"; -import { MonitoringSitesGroup } from "../../class/monitoring-sites-group"; +import { + MonitoringSitesGroup, + columnNameSiteGroup, +} from "../../class/monitoring-sites-group"; import { Page, Paginated } from "../../interfaces/page"; +import { + Router +} from "@angular/router"; const LIMIT = 10; -enum columnNameSiteGroup { - sites_group_name = "Nom", - nb_sites = "Nb. sites", - nb_visits = "Nb. visites", - sites_group_code = "Code", -} - @Component({ selector: "monitoring-sitesgroups", templateUrl: "./monitoring-sitesgroups.component.html", @@ -22,10 +22,21 @@ export class MonitoringSitesGroupsComponent implements OnInit { @Input() sitesGroups: MonitoringSitesGroup[]; @Input() columnNameSiteGroup: typeof columnNameSiteGroup = columnNameSiteGroup; - + @Input() sitesGroupsSelected: MonitoringSitesGroup; filters = {}; + displayDetails: boolean = false; + path: string; - constructor(private _sites_group_service: SitesGroupService) {} + constructor( + private _sites_group_service: SitesGroupService, + private router: Router, + private location: LocationStrategy + ) { + this.path = this.router.url; + this.location.onPopState(() => { + if (this.location.path() === this.path) this.displayDetails = false; + }); + } ngOnInit() { this.getSitesGroups(); } @@ -59,4 +70,17 @@ export class MonitoringSitesGroupsComponent implements OnInit { this.filters = filters; this.getSitesGroups(1, this.filters); } + + seeDetails($event) { + console.log("seeDetails", $event); + if ($event) { + this.displayDetails = true; + this.sitesGroupsSelected = $event; + this.router.navigate([ + "/monitorings/sites_groups", + $event.id_sites_group, + ]); + console.log(this.sitesGroupsSelected); + } + } } diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index 902bd7205..4b94a1094 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -27,7 +27,6 @@ import { MonitoringPropertiesComponent } from "./components/monitoring-propertie import { MonitoringDatatableComponent } from "./components/monitoring-datatable/monitoring-datatable.component"; import { MonitoringDatatableGComponent } from "./components/monitoring-datatable-g/monitoring-datatable-g.component"; - import { MatSlideToggleModule } from "@angular/material/slide-toggle"; import { MatFormFieldModule } from "@angular/material/form-field"; import { MatAutocompleteModule } from "@angular/material/autocomplete"; @@ -36,6 +35,7 @@ import { MatInputModule } from "@angular/material/input"; import { MonitoringSitesGroupsComponent } from "./components/monitoring-sitesgroups/monitoring-sitesgroups.component"; import { DataTableService } from "./services/data-table.service"; import { SitesGroupService } from "./services/sites_group.service"; +import { MonitoringPropertiesGComponent } from "./components/monitoring-properties-g/monitoring-properties-g.component"; // my module routing const routes: Routes = [ @@ -60,6 +60,12 @@ const routes: Routes = [ { path: "sites_groups", component: MonitoringSitesGroupsComponent, + children: [ + { + path: ":id", + component: MonitoringPropertiesGComponent, + }, + ], }, ]; @@ -76,7 +82,8 @@ const routes: Routes = [ MonitoringPropertiesComponent, MonitoringDatatableComponent, MonitoringSitesGroupsComponent, - MonitoringDatatableGComponent + MonitoringDatatableGComponent, + MonitoringPropertiesGComponent, ], imports: [ GN2CommonModule, From 8a4e43408c92b31bcaba6ac2b4336a81a15813ab Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Fri, 20 Jan 2023 17:35:55 +0100 Subject: [PATCH 14/44] feat: display groups sites's child Display group site child into table and uder properties Use routing and id params to display property of groups site Create service site Add logic to check routing and child route to display reactive component properties and table Reviewed-by: andriacap [Refs ticket]: #4 --- frontend/app/class/monitoring-site.ts | 13 ++ .../monitoring-datatable-g.component.html | 4 +- .../monitoring-sitesgroups.component.html | 8 +- .../monitoring-sitesgroups.component.ts | 142 ++++++++++++++++-- frontend/app/gnModule.module.ts | 4 + frontend/app/services/sites.service.ts | 98 +++--------- frontend/app/services/sites_group.service.ts | 43 +++++- 7 files changed, 217 insertions(+), 95 deletions(-) diff --git a/frontend/app/class/monitoring-site.ts b/frontend/app/class/monitoring-site.ts index e3003420c..990763c55 100644 --- a/frontend/app/class/monitoring-site.ts +++ b/frontend/app/class/monitoring-site.ts @@ -1,6 +1,19 @@ import { ISite, JsonData } from "../interfaces/geom"; import { GeoJSON } from "geojson"; +export enum columnNameSite{ + base_site_name = "Nom", + last_visit = "Dernière visite", + nb_visits = "Nb. visites", + base_site_code = "Code", + altitude_max = "Alt.max", + altitude_min = "Alt.min" +} + +export const extendedDetailsSite= { + ...columnNameSite, + base_site_description: "Description", +}; export class MonitoringSite implements ISite { altitude_max: number; altitude_min: number; diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html index cb8d1af18..cfc29c460 100644 --- a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html @@ -60,7 +60,7 @@ @@ -68,7 +68,7 @@ diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index af259537c..be0303b9f 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -16,15 +16,15 @@ -
+
diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 47612656a..a071bc459 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit, Input } from "@angular/core"; -import { LocationStrategy } from "@angular/common"; import { SitesGroupService } from "../../services/sites_group.service"; import { MonitoringSitesGroup, @@ -7,8 +6,15 @@ import { } from "../../class/monitoring-sites-group"; import { Page, Paginated } from "../../interfaces/page"; import { - Router + Router, + Event, + NavigationStart, + NavigationEnd, + NavigationError, + ActivatedRoute, } from "@angular/router"; +import { MonitoringSite, columnNameSite } from "../../class/monitoring-site"; +import { Subscription } from "rxjs"; const LIMIT = 10; @@ -20,25 +26,83 @@ const LIMIT = 10; export class MonitoringSitesGroupsComponent implements OnInit { @Input() page: Page; @Input() sitesGroups: MonitoringSitesGroup[]; + @Input() sitesChild: MonitoringSite[]; @Input() columnNameSiteGroup: typeof columnNameSiteGroup = columnNameSiteGroup; + @Input() columnNameSite: typeof columnNameSite = columnNameSite; @Input() sitesGroupsSelected: MonitoringSitesGroup; + + @Input() rows; + @Input() colsname; + @Input() obj; + filters = {}; displayDetails: boolean = false; path: string; + currentRoute: string = ""; + id: string | null; + + private routerSubscription: Subscription; constructor( private _sites_group_service: SitesGroupService, private router: Router, - private location: LocationStrategy - ) { - this.path = this.router.url; - this.location.onPopState(() => { - if (this.location.path() === this.path) this.displayDetails = false; + private _Activatedroute: ActivatedRoute + ) // private _routingService: RoutingService + { + // TODO: Try to refactor into routingService ? + // console.log(this.id) + // this.id = this._routingService.id + // console.log(this.id) + // // this._routingService.getIdChild() + // this._routingService.idChanging.subscribe(value =>{console.log(value)}) + // console.log(this.id) + + this.currentRoute = ""; + this.routerSubscription = this.router.events.subscribe((event: Event) => { + if (event instanceof NavigationStart) { + // Show progress spinner or progress bar + console.log("Route change detected"); + } + + if (event instanceof NavigationEnd) { + // Hide progress spinner or progress bar + this.currentRoute = event.url; + this.checkChildRoute(); + console.log(event); + console.log(this._Activatedroute.snapshot); + console.log(this._Activatedroute.snapshot.params); + console.log(this.id); + this.getDataAccordingTopath(); + } + + if (event instanceof NavigationError) { + // Hide progress spinner or progress bar + + // Present error to user + console.log(event.error); + } }); } ngOnInit() { - this.getSitesGroups(); + this.getDataAccordingTopath(); + } + + ngOnDestroy() { + this.routerSubscription.unsubscribe(); + } + + checkChildRoute() { + if (this._Activatedroute.firstChild) { + this._Activatedroute.firstChild.params.subscribe((params) => { + this.displayDetails = true; + this.id = params["id"]; + }); + } else { + this.displayDetails = false; + this.id = null; + } + // console.log(params); } getSitesGroups(page = 1, params = {}) { @@ -51,31 +115,83 @@ export class MonitoringSitesGroupsComponent implements OnInit { page: data.page - 1, }; this.sitesGroups = data.items; + this.rows = this.sitesGroups; + this.obj = this.sitesGroups; + this.colsname = this.columnNameSiteGroup; + console.log("Inside getSitesGroups", this.rows); }); } + getSitesGroupsById(page = 1, params = {}) { + this._sites_group_service + .get(page, LIMIT, params) + .subscribe((data: Paginated) => { + this.page = { + count: data.count, + limit: data.limit, + page: data.page - 1, + }; + this.sitesGroupsSelected = data.items[0]; + console.log("Inside getSitesGroupsById", data.items); + }); + } + + getSitesGroupsChild(page = 1, params = {}) { + console.log(params); + this._sites_group_service + .getSitesChild(page, LIMIT, params) + .subscribe((data: Paginated) => { + this.page = { + count: data.count, + limit: data.limit, + page: data.page - 1, + }; + + this.sitesChild = data.items; + this.rows = this.sitesChild; + this.obj = this.sitesChild; + this.colsname = this.columnNameSite; + console.log("Inside getSitesGroupsChild", this.rows); + }); + } + + getDataAccordingTopath(page = 1, params = {}) { + if (this.id) { + console.log("inside getDataAccording to path", this.id); + console.log("inside getDataAccording to path, params", params); + params["id_sites_group"] = this.id; + this.displayDetails = true; + this.getSitesGroupsById( + (page = 1), + (params = { id_sites_group: this.id }) + ); + this.getSitesGroupsChild(page, params); + } else { + this.getSitesGroups(page, params); + } + // }); + } + setPage($event) { console.log("setPage Sitesgroups Components"); - this.getSitesGroups($event.page + 1, this.filters); + this.getDataAccordingTopath($event.page + 1, this.filters); } onSortEvent(filters) { console.log("onSortEvent sitegroups component, filters", filters); this.filters = filters; - this.getSitesGroups(1, this.filters); + this.getDataAccordingTopath(1, this.filters); } onFilterEvent(filters) { console.log("onFilterEvent sitegroups component, filters", filters); this.filters = filters; - this.getSitesGroups(1, this.filters); + this.getDataAccordingTopath(1, this.filters); } seeDetails($event) { console.log("seeDetails", $event); if ($event) { - this.displayDetails = true; - this.sitesGroupsSelected = $event; this.router.navigate([ "/monitorings/sites_groups", $event.id_sites_group, diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index 4b94a1094..321cbcd61 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -36,6 +36,8 @@ import { MonitoringSitesGroupsComponent } from "./components/monitoring-sitesgro import { DataTableService } from "./services/data-table.service"; import { SitesGroupService } from "./services/sites_group.service"; import { MonitoringPropertiesGComponent } from "./components/monitoring-properties-g/monitoring-properties-g.component"; +import { SitesService } from "./services/sites.service"; +// import { RoutingService } from "./services/routing.service"; // my module routing const routes: Routes = [ @@ -109,6 +111,8 @@ const routes: Routes = [ MonitoringObjectService, DataTableService, SitesGroupService, + SitesService, + // RoutingService ], bootstrap: [ModulesComponent], schemas: [ diff --git a/frontend/app/services/sites.service.ts b/frontend/app/services/sites.service.ts index 1b6ec315b..9a3f10adf 100644 --- a/frontend/app/services/sites.service.ts +++ b/frontend/app/services/sites.service.ts @@ -1,81 +1,31 @@ import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +// import { GeoJSON } from "geojson"; import { CacheService } from "./cache.service"; -import { ConfigService } from "./config.service"; -import { HttpClient } from "@angular/common/http"; -import { GeoJSON } from "leaflet"; -interface SitesGroups{ - comments?: string; - data?: any; - // geometry: any; - id_sites_group: number; - nb_sites: number; - nb_visits: number; - sites_group_code: string; - sites_group_description?: string; - sites_group_name: string; - uuid_sites_group: string; -} - -interface SitesGroupsExtended extends Omit { - // properties:Omit; - properties:SitesGroups - type:string; -} - -interface Page { - count: number; - limit: number; - page: number; -} - -interface PaginatedSitesGroup extends Page{ - items: SitesGroupsExtended[]; -} -interface CustomGeoJson { - type: "FeatureCollection"; - features: SitesGroupsExtended[]; -} +import { IGeomService, JsonData, ISite } from "../interfaces/geom"; +import { Paginated } from "../interfaces/page"; +import { MonitoringSite } from "../class/monitoring-site"; @Injectable() -export class SitesService { - constructor( - private _cacheService: CacheService - ) {} - - getSitesGroups(page=1, limit=10, params={}) { - return this._cacheService.request("get", `sites_groups`, {queryParams: {page, limit, ...params}}); - } - - setFormatToGeoJson(data:PaginatedSitesGroup):CustomGeoJson{ - return { - features: data.items.map((group) => { - let { - geometry, - properties, - ..._ - } = group; - let result = {"geometry":geometry,"properties":properties,"type":"Feature"} - console.log("result",result) - console.log(group) - return result; - }), - type: "FeatureCollection", - }; +export class SitesService implements IGeomService { + constructor(private _cacheService: CacheService) {} + + get( + page: number = 1, + limit: number = 10, + params: JsonData = {} + ): Observable> { + return this._cacheService + .request>>("get", `sites`, { + queryParams: { page, limit, ...params }, + }) + .pipe( + map((response: Paginated) => ({ + ...response, + items: response.items.map((item: ISite) => item as MonitoringSite), + })) + ); } - - getDataTable(data:CustomGeoJson) { - return data.features.map((groupSite) => { - let { - comments, - data, - uuid_sites_group, - id_sites_group, - sites_group_description, - ...dataTable - } = groupSite.properties; - return dataTable; - }); - } - } diff --git a/frontend/app/services/sites_group.service.ts b/frontend/app/services/sites_group.service.ts index fd8f10b5d..9271224d2 100644 --- a/frontend/app/services/sites_group.service.ts +++ b/frontend/app/services/sites_group.service.ts @@ -4,10 +4,10 @@ import { map } from "rxjs/operators"; // import { GeoJSON } from "geojson"; import { CacheService } from "./cache.service"; -import { IGeomService, JsonData, ISitesGroup } from "../interfaces/geom"; +import { IGeomService, JsonData, ISitesGroup, ISite } from "../interfaces/geom"; import { Paginated } from "../interfaces/page"; import { MonitoringSitesGroup } from "../class/monitoring-sites-group"; - +import { MonitoringSite } from "../class/monitoring-site"; @Injectable() export class SitesGroupService implements IGeomService { constructor(private _cacheService: CacheService) {} @@ -30,4 +30,43 @@ export class SitesGroupService implements IGeomService { })) ); } + + // getById( + // page: number = 1, + // limit: number = 10, + // params: JsonData = {"id_sites_group":null} + // ): Observable> { + // return this._cacheService + // .request>>("get", `sites_groups`, { + // queryParams: { page, limit, ...params }, + // }) + // .pipe( + // map((response: Paginated) => ({ + // ...response, + // items: response.items.map( + // (item: ISitesGroup) => item as MonitoringSitesGroup + // ), + // })) + // ); + // } + + + getSitesChild(page: number = 1, + limit: number = 10, + params: JsonData = {}, + ): Observable> { + return this._cacheService + .request>>("get", `sites`, { + queryParams: { page, limit, ...params }, + }) + .pipe( + map((response: Paginated) => ({ + ...response, + items: response.items.map( + (item: ISite) => item as MonitoringSite + ), + })) + ); + } + } From f965a6ab86cbb36b5208b97ea9f768af40fa2944 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Thu, 19 Jan 2023 15:42:13 +0100 Subject: [PATCH 15/44] refactor(front): rename interfaces, remove classes Better types --- frontend/app/class/monitoring-site.ts | 60 +------------------ frontend/app/class/monitoring-sites-group.ts | 37 ------------ .../monitoring-properties-g.component.ts | 6 +- .../monitoring-sitesgroups.component.ts | 20 +++---- frontend/app/interfaces/column.ts | 2 +- frontend/app/interfaces/geom.ts | 9 ++- frontend/app/interfaces/page.ts | 4 +- frontend/app/services/data-table.service.ts | 6 +- frontend/app/services/sites.service.ts | 25 ++++---- frontend/app/services/sites_group.service.ts | 54 +++++++---------- frontend/app/types/jsondata.ts | 1 + 11 files changed, 57 insertions(+), 167 deletions(-) create mode 100644 frontend/app/types/jsondata.ts diff --git a/frontend/app/class/monitoring-site.ts b/frontend/app/class/monitoring-site.ts index 990763c55..d33650386 100644 --- a/frontend/app/class/monitoring-site.ts +++ b/frontend/app/class/monitoring-site.ts @@ -1,67 +1,13 @@ -import { ISite, JsonData } from "../interfaces/geom"; -import { GeoJSON } from "geojson"; - -export enum columnNameSite{ +export enum columnNameSite { base_site_name = "Nom", last_visit = "Dernière visite", nb_visits = "Nb. visites", base_site_code = "Code", altitude_max = "Alt.max", - altitude_min = "Alt.min" + altitude_min = "Alt.min", } -export const extendedDetailsSite= { +export const extendedDetailsSite = { ...columnNameSite, base_site_description: "Description", }; -export class MonitoringSite implements ISite { - altitude_max: number; - altitude_min: number; - base_site_code: string; - base_site_description?: string; - base_site_name: string; - data: JsonData; - first_use_date: string; - geometry: GeoJSON.FeatureCollection; - id_base_site: number; - id_nomenclature_type_site?: number; - last_visit?: Date; - meta_create_date: Date; - meta_update_date: Date; - nb_visits: number; - uuid_base_site: string; - - constructor( - altitude_max: number, - altitude_min: number, - base_site_code: string, - base_site_description: string, - base_site_name: string, - data: JsonData, - geometry: GeoJSON.FeatureCollection, - first_use_date: string, - id_base_site: number, - id_nomenclature_type_site: number, - last_visit: Date, - meta_create_date: Date, - meta_update_date: Date, - nb_visits: number, - uuid_base_site: string - ) { - this.altitude_max = altitude_max; - this.altitude_min = altitude_min; - this.base_site_code = base_site_code; - this.base_site_description = base_site_description; - this.base_site_name = base_site_name; - this.data = data; - this.first_use_date = first_use_date; - this.geometry = geometry; - this.id_base_site = id_base_site; - this.id_nomenclature_type_site = id_nomenclature_type_site; - this.last_visit = last_visit; - this.meta_create_date = meta_create_date; - this.meta_update_date = meta_update_date; - this.nb_visits = nb_visits; - this.uuid_base_site = uuid_base_site; - } -} diff --git a/frontend/app/class/monitoring-sites-group.ts b/frontend/app/class/monitoring-sites-group.ts index 8bed67806..21ae7f540 100644 --- a/frontend/app/class/monitoring-sites-group.ts +++ b/frontend/app/class/monitoring-sites-group.ts @@ -1,6 +1,3 @@ -import { ISitesGroup, JsonData } from "../interfaces/geom"; -import { GeoJSON } from "geojson"; - export enum columnNameSiteGroup { sites_group_name = "Nom", nb_sites = "Nb. sites", @@ -14,37 +11,3 @@ export const extendedDetailsSiteGroup = { sites_group_description: "Description", }; // export type detailsSiteGroups = columnNameSiteGroup | extendedDetailsSiteGroup - -export class MonitoringSitesGroup implements ISitesGroup { - id_sites_group: number; - sites_group_name: string; - sites_group_code: string; - sites_group_description: string; - geometry: GeoJSON.FeatureCollection; - data: JsonData; - nb_sites: number; - nb_visits: number; - uuid_sites_group: string; //FIXME: see if OK - - constructor( - id_sites_group: number, - sites_group_name: string, - sites_group_code: string, - sites_group_description: string, - geometry: GeoJSON.FeatureCollection, - data: JsonData, - nb_sites: number, - nb_visits: number, - uuid_sites_group: string = "" //FIXME: see if OK - ) { - this.id_sites_group = id_sites_group; - this.sites_group_name = sites_group_name; - this.sites_group_code = sites_group_code; - this.sites_group_description = sites_group_description; - this.geometry = geometry; - this.data = data; - this.nb_sites = nb_sites; - this.nb_visits = nb_visits; - this.uuid_sites_group = uuid_sites_group; - } -} diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts index 0fc3b71f4..c9967b46c 100644 --- a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts @@ -8,9 +8,9 @@ import { } from "@angular/core"; import { FormControl } from "@angular/forms"; import { - MonitoringSitesGroup, extendedDetailsSiteGroup, } from "../../class/monitoring-sites-group"; +import { ISitesGroup } from "../../interfaces/geom"; @Component({ selector: "pnx-monitoring-properties-g", @@ -18,7 +18,7 @@ import { styleUrls: ["./monitoring-properties-g.component.css"], }) export class MonitoringPropertiesGComponent implements OnInit { - @Input() selectedObj: MonitoringSitesGroup; + @Input() selectedObj: ISitesGroup; @Input() bEdit: boolean; @Output() bEditChange = new EventEmitter(); @@ -28,7 +28,7 @@ export class MonitoringPropertiesGComponent implements OnInit { infosColsSiteGroups: typeof extendedDetailsSiteGroup = extendedDetailsSiteGroup; color: string = "white"; - dataDetails: MonitoringSitesGroup; + dataDetails: ISitesGroup; datasetForm = new FormControl(); bUpdateSyntheseSpinner = false; diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index a071bc459..a3f6a56d9 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -1,10 +1,9 @@ import { Component, OnInit, Input } from "@angular/core"; import { SitesGroupService } from "../../services/sites_group.service"; import { - MonitoringSitesGroup, columnNameSiteGroup, } from "../../class/monitoring-sites-group"; -import { Page, Paginated } from "../../interfaces/page"; +import { IPaginated, IPage } from "../../interfaces/page"; import { Router, Event, @@ -13,8 +12,9 @@ import { NavigationError, ActivatedRoute, } from "@angular/router"; -import { MonitoringSite, columnNameSite } from "../../class/monitoring-site"; +import { columnNameSite } from "../../class/monitoring-site"; import { Subscription } from "rxjs"; +import { ISite, ISitesGroup } from "../../interfaces/geom"; const LIMIT = 10; @@ -24,13 +24,13 @@ const LIMIT = 10; styleUrls: ["./monitoring-sitesgroups.component.css"], }) export class MonitoringSitesGroupsComponent implements OnInit { - @Input() page: Page; - @Input() sitesGroups: MonitoringSitesGroup[]; - @Input() sitesChild: MonitoringSite[]; + @Input() page: IPage; + @Input() sitesGroups: ISitesGroup[]; + @Input() sitesChild: ISite[]; @Input() columnNameSiteGroup: typeof columnNameSiteGroup = columnNameSiteGroup; @Input() columnNameSite: typeof columnNameSite = columnNameSite; - @Input() sitesGroupsSelected: MonitoringSitesGroup; + @Input() sitesGroupsSelected: ISitesGroup; @Input() rows; @Input() colsname; @@ -108,7 +108,7 @@ export class MonitoringSitesGroupsComponent implements OnInit { getSitesGroups(page = 1, params = {}) { this._sites_group_service .get(page, LIMIT, params) - .subscribe((data: Paginated) => { + .subscribe((data: IPaginated) => { this.page = { count: data.count, limit: data.limit, @@ -125,7 +125,7 @@ export class MonitoringSitesGroupsComponent implements OnInit { getSitesGroupsById(page = 1, params = {}) { this._sites_group_service .get(page, LIMIT, params) - .subscribe((data: Paginated) => { + .subscribe((data: IPaginated) => { this.page = { count: data.count, limit: data.limit, @@ -140,7 +140,7 @@ export class MonitoringSitesGroupsComponent implements OnInit { console.log(params); this._sites_group_service .getSitesChild(page, LIMIT, params) - .subscribe((data: Paginated) => { + .subscribe((data: IPaginated) => { this.page = { count: data.count, limit: data.limit, diff --git a/frontend/app/interfaces/column.ts b/frontend/app/interfaces/column.ts index 2f395be28..82f803037 100644 --- a/frontend/app/interfaces/column.ts +++ b/frontend/app/interfaces/column.ts @@ -1,4 +1,4 @@ -export interface Column { +export interface IColumn { name: string; prop: string; description?: string; diff --git a/frontend/app/interfaces/geom.ts b/frontend/app/interfaces/geom.ts index 3bbeb5fdb..f464fc48b 100644 --- a/frontend/app/interfaces/geom.ts +++ b/frontend/app/interfaces/geom.ts @@ -1,12 +1,11 @@ import { GeoJSON } from "geojson"; import { Observable } from "rxjs"; -import { Paginated } from "./page"; - -export type JsonData = { [key: string]: any }; +import { JsonData } from "../types/jsondata"; +import { IPaginated } from "./page"; export interface IGeomObject { data: JsonData; - geometry: GeoJSON.FeatureCollection; + geometry: GeoJSON.Geometry; } export interface ISitesGroup extends IGeomObject { @@ -41,7 +40,7 @@ export interface IGeomService { limit: number, page: number, params: JsonData - ): Observable>; + ): Observable>; // get_geometries(): GeoJson // create(obj: IGeomObject) // patch(obj: IGeomObject) diff --git a/frontend/app/interfaces/page.ts b/frontend/app/interfaces/page.ts index 1f41f6a84..b1541dae0 100644 --- a/frontend/app/interfaces/page.ts +++ b/frontend/app/interfaces/page.ts @@ -1,9 +1,9 @@ -export interface Page { +export interface IPage { count: number; limit: number; page: number; } -export interface Paginated extends Page { +export interface IPaginated extends IPage { items: T[]; } diff --git a/frontend/app/services/data-table.service.ts b/frontend/app/services/data-table.service.ts index 0d17d5687..6f350182b 100644 --- a/frontend/app/services/data-table.service.ts +++ b/frontend/app/services/data-table.service.ts @@ -1,5 +1,5 @@ import { Injectable } from "@angular/core"; -import { Column } from "../interfaces/column"; +import { IColumn } from "../interfaces/column"; interface ItemObjectTable { id: number | null; @@ -19,9 +19,9 @@ export class DataTableService { constructor() {} - colsTable(colName, dataTable): Column[] { + colsTable(colName, dataTable): IColumn[] { const arr = Object.keys(colName); - const allColumn: Column[] = arr + const allColumn: IColumn[] = arr .filter((item) => Object.keys(dataTable).includes(item)) .map((elm) => ({ name: colName[elm], diff --git a/frontend/app/services/sites.service.ts b/frontend/app/services/sites.service.ts index 9a3f10adf..1d13e026e 100644 --- a/frontend/app/services/sites.service.ts +++ b/frontend/app/services/sites.service.ts @@ -1,12 +1,10 @@ import { Injectable } from "@angular/core"; import { Observable } from "rxjs"; -import { map } from "rxjs/operators"; -// import { GeoJSON } from "geojson"; import { CacheService } from "./cache.service"; -import { IGeomService, JsonData, ISite } from "../interfaces/geom"; -import { Paginated } from "../interfaces/page"; -import { MonitoringSite } from "../class/monitoring-site"; +import { IGeomService, ISite } from "../interfaces/geom"; +import { IPaginated } from "../interfaces/page"; +import { JsonData } from "../types/jsondata"; @Injectable() export class SitesService implements IGeomService { @@ -16,16 +14,13 @@ export class SitesService implements IGeomService { page: number = 1, limit: number = 10, params: JsonData = {} - ): Observable> { - return this._cacheService - .request>>("get", `sites`, { + ): Observable> { + return this._cacheService.request>>( + "get", + `sites`, + { queryParams: { page, limit, ...params }, - }) - .pipe( - map((response: Paginated) => ({ - ...response, - items: response.items.map((item: ISite) => item as MonitoringSite), - })) - ); + } + ); } } diff --git a/frontend/app/services/sites_group.service.ts b/frontend/app/services/sites_group.service.ts index 9271224d2..27ae0217d 100644 --- a/frontend/app/services/sites_group.service.ts +++ b/frontend/app/services/sites_group.service.ts @@ -1,13 +1,10 @@ import { Injectable } from "@angular/core"; import { Observable } from "rxjs"; -import { map } from "rxjs/operators"; -// import { GeoJSON } from "geojson"; import { CacheService } from "./cache.service"; -import { IGeomService, JsonData, ISitesGroup, ISite } from "../interfaces/geom"; -import { Paginated } from "../interfaces/page"; -import { MonitoringSitesGroup } from "../class/monitoring-sites-group"; -import { MonitoringSite } from "../class/monitoring-site"; +import { IGeomService, ISitesGroup, ISite } from "../interfaces/geom"; +import { IPaginated } from "../interfaces/page"; +import { JsonData } from "../types/jsondata"; @Injectable() export class SitesGroupService implements IGeomService { constructor(private _cacheService: CacheService) {} @@ -16,19 +13,14 @@ export class SitesGroupService implements IGeomService { page: number = 1, limit: number = 10, params: JsonData = {} - ): Observable> { - return this._cacheService - .request>>("get", `sites_groups`, { + ): Observable> { + return this._cacheService.request>>( + "get", + `sites_groups`, + { queryParams: { page, limit, ...params }, - }) - .pipe( - map((response: Paginated) => ({ - ...response, - items: response.items.map( - (item: ISitesGroup) => item as MonitoringSitesGroup - ), - })) - ); + } + ); } // getById( @@ -50,23 +42,17 @@ export class SitesGroupService implements IGeomService { // ); // } - - getSitesChild(page: number = 1, + getSitesChild( + page: number = 1, limit: number = 10, - params: JsonData = {}, - ): Observable> { - return this._cacheService - .request>>("get", `sites`, { + params: JsonData = {} + ): Observable> { + return this._cacheService.request>>( + "get", + `sites`, + { queryParams: { page, limit, ...params }, - }) - .pipe( - map((response: Paginated) => ({ - ...response, - items: response.items.map( - (item: ISite) => item as MonitoringSite - ), - })) - ); + } + ); } - } diff --git a/frontend/app/types/jsondata.ts b/frontend/app/types/jsondata.ts new file mode 100644 index 000000000..fa13d6798 --- /dev/null +++ b/frontend/app/types/jsondata.ts @@ -0,0 +1 @@ +export type JsonData = { [key: string]: any }; From c5e19171d354a0d5c09526cffea6fcb88d25c530 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Mon, 23 Jan 2023 16:48:22 +0100 Subject: [PATCH 16/44] feat(front): get all geometries For sites and sites_groups --- .../monitoring-sitesgroups.component.html | 2 +- .../monitoring-sitesgroups.component.ts | 22 +++++++++++++++++++ frontend/app/interfaces/geom.ts | 2 +- frontend/app/services/sites.service.ts | 12 ++++++++++ frontend/app/services/sites_group.service.ts | 11 ++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index be0303b9f..d911a6c98 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -2,7 +2,7 @@
diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index a3f6a56d9..f87189333 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit, Input } from "@angular/core"; +import { GeoJSON } from "geojson"; import { SitesGroupService } from "../../services/sites_group.service"; import { columnNameSiteGroup, @@ -15,6 +16,7 @@ import { import { columnNameSite } from "../../class/monitoring-site"; import { Subscription } from "rxjs"; import { ISite, ISitesGroup } from "../../interfaces/geom"; +import { SitesService } from "../../services/sites.service"; const LIMIT = 10; @@ -41,11 +43,13 @@ export class MonitoringSitesGroupsComponent implements OnInit { path: string; currentRoute: string = ""; id: string | null; + geojson: GeoJSON.FeatureCollection; private routerSubscription: Subscription; constructor( private _sites_group_service: SitesGroupService, + private _sites_service: SitesService, private router: Router, private _Activatedroute: ActivatedRoute ) // private _routingService: RoutingService @@ -122,6 +126,22 @@ export class MonitoringSitesGroupsComponent implements OnInit { }); } + getSitesGroupsGeometries(params = {}) { + this._sites_group_service + .get_geometries(params) + .subscribe((data: GeoJSON.FeatureCollection) => { + this.geojson = data + }) + } + + getSitesGroupsChildGeometries(params = {}) { + this._sites_service + .get_geometries(params) + .subscribe((data: GeoJSON.FeatureCollection) => { + this.geojson = data + }) + } + getSitesGroupsById(page = 1, params = {}) { this._sites_group_service .get(page, LIMIT, params) @@ -166,7 +186,9 @@ export class MonitoringSitesGroupsComponent implements OnInit { (params = { id_sites_group: this.id }) ); this.getSitesGroupsChild(page, params); + this.getSitesGroupsChildGeometries({ id_sites_group: this.id}) } else { + this.getSitesGroupsGeometries(params) this.getSitesGroups(page, params); } // }); diff --git a/frontend/app/interfaces/geom.ts b/frontend/app/interfaces/geom.ts index f464fc48b..6cdcc90f9 100644 --- a/frontend/app/interfaces/geom.ts +++ b/frontend/app/interfaces/geom.ts @@ -41,7 +41,7 @@ export interface IGeomService { page: number, params: JsonData ): Observable>; - // get_geometries(): GeoJson + get_geometries(): Observable; // create(obj: IGeomObject) // patch(obj: IGeomObject) // delete(obj: IGeomObject) diff --git a/frontend/app/services/sites.service.ts b/frontend/app/services/sites.service.ts index 1d13e026e..8a001a8e9 100644 --- a/frontend/app/services/sites.service.ts +++ b/frontend/app/services/sites.service.ts @@ -1,5 +1,6 @@ import { Injectable } from "@angular/core"; import { Observable } from "rxjs"; +import { GeoJSON } from "geojson" import { CacheService } from "./cache.service"; import { IGeomService, ISite } from "../interfaces/geom"; @@ -23,4 +24,15 @@ export class SitesService implements IGeomService { } ); } + + get_geometries(params: JsonData = {}): Observable { + return this._cacheService.request>( + "get", + "/sites/geometries", + { + queryParams: { ...params }, + } + ); + } + } diff --git a/frontend/app/services/sites_group.service.ts b/frontend/app/services/sites_group.service.ts index 27ae0217d..5aa4a6ed8 100644 --- a/frontend/app/services/sites_group.service.ts +++ b/frontend/app/services/sites_group.service.ts @@ -1,5 +1,6 @@ import { Injectable } from "@angular/core"; import { Observable } from "rxjs"; +import { GeoJSON } from "geojson"; import { CacheService } from "./cache.service"; import { IGeomService, ISitesGroup, ISite } from "../interfaces/geom"; @@ -42,6 +43,16 @@ export class SitesGroupService implements IGeomService { // ); // } + get_geometries(params: JsonData = {}): Observable { + return this._cacheService.request>( + "get", + "/sites_groups/geometries", + { + queryParams: { ...params }, + } + ); + } + getSitesChild( page: number = 1, limit: number = 10, From 7580095e3fc36abbb2758834314634a7bf3180c1 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Tue, 24 Jan 2023 14:37:08 +0100 Subject: [PATCH 17/44] feat(front): WIP: geojson service to create layers And features groups since geojson component accumulated layers without cleaning them... --- .../monitoring-sitesgroups.component.html | 8 +- .../monitoring-sitesgroups.component.ts | 41 +++------ frontend/app/gnModule.module.ts | 2 + frontend/app/services/geojson.service.ts | 86 +++++++++++++++++++ 4 files changed, 103 insertions(+), 34 deletions(-) create mode 100644 frontend/app/services/geojson.service.ts diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index d911a6c98..7e4bf6e61 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -1,12 +1,6 @@
- - - +
-
+ + + +
+
diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 44fe7b978..f37739abd 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -17,30 +17,20 @@ import { columnNameSite } from "../../class/monitoring-site"; import { ISite, ISitesGroup } from "../../interfaces/geom"; import { SitesService } from "../../services/sites.service"; import { GeoJSONService } from "../../services/geojson.service"; +import { MonitoringGeomComponent } from "../../class/monitoring-geom-component"; +import { setPopup } from "../../functions/popup"; const LIMIT = 10; -function setPopup(baseUrl: string, id: number, name: string) { - const url = `#/${baseUrl}/${id}/`; - - const popup = ` -
-

${name}

- - - -
- `; - - return popup; -} - @Component({ selector: "monitoring-sitesgroups", templateUrl: "./monitoring-sitesgroups.component.html", styleUrls: ["./monitoring-sitesgroups.component.css"], }) -export class MonitoringSitesGroupsComponent implements OnInit { +export class MonitoringSitesGroupsComponent + extends MonitoringGeomComponent + implements OnInit +{ @Input() page: IPage; @Input() sitesGroups: ISitesGroup[]; @Input() sitesChild: ISite[]; @@ -59,60 +49,32 @@ export class MonitoringSitesGroupsComponent implements OnInit { currentRoute: string = ""; id: string | null; - private routerSubscription: Subscription; - constructor( private _sites_group_service: SitesGroupService, private _sites_service: SitesService, - public geojson_service: GeoJSONService, + public geojsonService: GeoJSONService, private _configService: ConfigService, private router: Router, private _Activatedroute: ActivatedRoute // private _routingService: RoutingService ) { - // TODO: Try to refactor into routingService ? - // console.log(this.id) - // this.id = this._routingService.id - // console.log(this.id) - // // this._routingService.getIdChild() - // this._routingService.idChanging.subscribe(value =>{console.log(value)}) - // console.log(this.id) - - this.currentRoute = ""; - this.routerSubscription = this.router.events.subscribe((event: Event) => { - if (event instanceof NavigationStart) { - // Show progress spinner or progress bar - console.log("Route change detected"); - } - - if (event instanceof NavigationEnd) { - // Hide progress spinner or progress bar - this.currentRoute = event.url; - this.checkChildRoute(); - console.log(event); - console.log(this._Activatedroute.snapshot); - console.log(this._Activatedroute.snapshot.params); - console.log(this.id); - this.getDataAccordingTopath(); - } - - if (event instanceof NavigationError) { - // Hide progress spinner or progress bar - - // Present error to user - console.log(event.error); - } - }); + super(); + this.getAllItemsCallback = this.getSitesGroups; } ngOnInit() { - this.getDataAccordingTopath(); + this.getSitesGroups(1); + this.geojsonService.getSitesGroupsGeometries( + this.onEachFeatureSiteGroups() + ); } ngOnDestroy() { - this.routerSubscription.unsubscribe(); + this.geojsonService.removeFeatureGroup( + this.geojsonService.sitesGroupFeatureGroup + ); } - onEachFeatureSiteGroups() { + onEachFeatureSiteGroups(): Function { const baseUrl = this.router.url; return (feature, layer) => { const popup = setPopup( @@ -124,37 +86,6 @@ export class MonitoringSitesGroupsComponent implements OnInit { }; } - onEachFeatureSite() { - const baseUrl = this.router.url; - return (feature, layer) => { - const popup = setPopup( - baseUrl, - feature.properties.id_base_site, - "Site :" + feature.properties.base_site_name - ); - layer.bindPopup(popup); - }; - } - - checkChildRoute() { - if (this._Activatedroute.firstChild) { - this._Activatedroute.firstChild.params.subscribe((params) => { - this.displayDetails = true; - this.id = params["id"]; - }); - } else { - this.displayDetails = false; - this.id = null; - this.geojson_service.removeFeatureGroup( - this.geojson_service.sitesFeatureGroup - ); - this.geojson_service.getSitesGroupsGeometries( - this.onEachFeatureSiteGroups() - ); - } - // console.log(params); - } - getSitesGroups(page = 1, params = {}) { this._sites_group_service .get(page, LIMIT, params) @@ -165,97 +96,26 @@ export class MonitoringSitesGroupsComponent implements OnInit { page: data.page - 1, }; this.sitesGroups = data.items; - this.rows = this.sitesGroups; - this.obj = this.sitesGroups; this.colsname = this.columnNameSiteGroup; - console.log("Inside getSitesGroups", this.rows); - }); - } - - getSitesGroupsById(page = 1, params = {}) { - this._sites_group_service - .get(page, LIMIT, params) - .subscribe((data: IPaginated) => { - this.page = { - count: data.count, - limit: data.limit, - page: data.page - 1, - }; - this.sitesGroupsSelected = data.items[0]; - console.log("Inside getSitesGroupsById", data.items); - }); - } - - getSitesGroupsChild(page = 1, params = {}) { - console.log(params); - this._sites_group_service - .getSitesChild(page, LIMIT, params) - .subscribe((data: IPaginated) => { - this.page = { - count: data.count, - limit: data.limit, - page: data.page - 1, - }; - - this.sitesChild = data.items; - this.rows = this.sitesChild; - this.obj = this.sitesChild; - this.colsname = this.columnNameSite; - console.log("Inside getSitesGroupsChild", this.rows); }); } - getDataAccordingTopath(page = 1, params = {}) { - if (this.id) { - console.log("inside getDataAccording to path", this.id); - console.log("inside getDataAccording to path, params", params); - params["id_sites_group"] = this.id; - this.displayDetails = true; - this.getSitesGroupsById( - (page = 1), - (params = { id_sites_group: this.id }) - ); - this.geojson_service.getSitesGroupsChildGeometries( - this.onEachFeatureSite(), - params - ); - this.geojson_service.filterSitesGroups(+this.id); - this.getSitesGroupsChild(page, params); - } else { - this.getSitesGroups(page, params); - } - // }); - } - - setPage($event) { - console.log("setPage Sitesgroups Components"); - this.getDataAccordingTopath($event.page + 1, this.filters); - } - - onSortEvent(filters) { - console.log("onSortEvent sitegroups component, filters", filters); - this.filters = filters; - this.getDataAccordingTopath(1, this.filters); - } - - onFilterEvent(filters) { - console.log("onFilterEvent sitegroups component, filters", filters); - this.filters = filters; - this.getDataAccordingTopath(1, this.filters); - } - seeDetails($event) { - console.log("seeDetails", $event); - if ($event) { - this.router.navigate([ - "/monitorings/sites_groups", - $event.id_sites_group, - ]); - console.log(this.sitesGroupsSelected); - } + // TODO: routerLink + console.log("seeDetails"); + this.router.navigate([$event.id_sites_group], { + relativeTo: this._Activatedroute, + }); + // if ($event) { + // this.router.navigate([ + // "/monitorings/sites_groups", + // $event.id_sites_group, + // ]); + // console.log(this.sitesGroupsSelected); + // } } onSelect($event) { - this.geojson_service.selectSitesGroupLayer($event); + this.geojsonService.selectSitesGroupLayer($event); } } diff --git a/frontend/app/functions/popup.ts b/frontend/app/functions/popup.ts new file mode 100644 index 000000000..e6e22b90c --- /dev/null +++ b/frontend/app/functions/popup.ts @@ -0,0 +1,14 @@ +export function setPopup(baseUrl: string, id: number, name: string) { + const url = `#/${baseUrl}/${id}/`; + + const popup = ` +
+

${name}

+ + + +
+ `; + + return popup; +} diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index 267382c9d..aef805c79 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -38,6 +38,8 @@ import { SitesGroupService } from "./services/sites_group.service"; import { MonitoringPropertiesGComponent } from "./components/monitoring-properties-g/monitoring-properties-g.component"; import { SitesService } from "./services/sites.service"; import { GeoJSONService } from "./services/geojson.service"; +import { MonitoringSitesComponent } from "./components/monitoring-sites/monitoring-sites.component"; +import { MonitoringMapListComponent } from "./components/monitoring-map-list/monitoring-map-list.component"; // import { RoutingService } from "./services/routing.service"; // my module routing @@ -62,11 +64,15 @@ const routes: Routes = [ }, { path: "sites_groups", - component: MonitoringSitesGroupsComponent, + component: MonitoringMapListComponent, children: [ + { + path: "", + component: MonitoringSitesGroupsComponent, + }, { path: ":id", - component: MonitoringPropertiesGComponent, + component: MonitoringSitesComponent, }, ], }, @@ -84,7 +90,9 @@ const routes: Routes = [ MonitoringListComponent, MonitoringPropertiesComponent, MonitoringDatatableComponent, + MonitoringMapListComponent, MonitoringSitesGroupsComponent, + MonitoringSitesComponent, MonitoringDatatableGComponent, MonitoringPropertiesGComponent, ], diff --git a/frontend/app/interfaces/page.ts b/frontend/app/interfaces/page.ts index b1541dae0..cca644c5f 100644 --- a/frontend/app/interfaces/page.ts +++ b/frontend/app/interfaces/page.ts @@ -7,3 +7,11 @@ export interface IPage { export interface IPaginated extends IPage { items: T[]; } + +// PageInfo = object given by ngx-datatable +export interface PageInfo { + offset: number; + pageSize: number; + limit: number; + count: number; +} From 409d81f2cbe2ed8ac01290256e144754f815015f Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Fri, 27 Jan 2023 16:37:34 +0100 Subject: [PATCH 24/44] fix(front): fix filters by adding baseFilters --- frontend/app/class/monitoring-geom-component.ts | 6 +++--- .../monitoring-sites/monitoring-sites.component.ts | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/app/class/monitoring-geom-component.ts b/frontend/app/class/monitoring-geom-component.ts index 8aa88bb2e..acad9b05b 100644 --- a/frontend/app/class/monitoring-geom-component.ts +++ b/frontend/app/class/monitoring-geom-component.ts @@ -9,6 +9,7 @@ export class MonitoringGeomComponent { protected getAllItemsCallback: callbackFunction; protected limit = LIMIT; public filters = {}; + public baseFilters = {}; constructor() {} @@ -17,14 +18,13 @@ export class MonitoringGeomComponent { } setSort(filters: JsonData) { - this.filters = filters; + this.filters = { ...this.baseFilters, ...filters }; const pageNumber = 1; this.getAllItemsCallback(pageNumber, this.filters); } setFilter(filters) { - console.log("onFilterEvent sitegroups component, filters", filters); - this.filters = filters; + this.filters = { ...this.baseFilters, ...filters }; this.getAllItemsCallback(1, this.filters); } } diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts index 7c247757e..7116ab9fa 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts +++ b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts @@ -39,6 +39,7 @@ export class MonitoringSitesComponent super(); this.getAllItemsCallback = this.getSitesFromSiteGroupId; } + ngOnInit() { this._Activatedroute.params .pipe( @@ -71,6 +72,7 @@ export class MonitoringSitesComponent data.sitesGroup.geometry, () => {} ); + this.baseFilters = { id_sites_group: this.sitesGroup.id_sites_group }; } ); } From 274843119df7b7ee138299b8b96831a1f760602f Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Tue, 31 Jan 2023 19:26:13 +0100 Subject: [PATCH 25/44] feat: edit sitegroups Create edit-service Create observable to update object to edit according to form component Adapt function service of monitoring object to sites and sitesgroups WIP: - adapt remaining function of monitoring object inside form-component-g - create an object which inherit of patch/post/delete method with - think about object with ObjectType of sites_group , sites, observation ? , visit ? - reload properties or update data of properties table after update data Reviewed-by:andriacap [Refs_ticket]: #4 --- .gitignore | 1 + .../gn_module_monitoring/monitoring/models.py | 43 +- .../monitoring/schemas.py | 6 +- .../routes/sites_groups.py | 42 ++ .../utils/errors/__init__.py | 0 .../utils/errors/errorHandler.py | 30 ++ .../utils/strings/__init__.py | 0 .../utils/strings/en-gb.json | 8 + .../utils/strings/strings.py | 25 ++ config/monitoring/generic/config.json | 3 +- .../components/modules/modules.component.html | 2 +- .../monitoring-datatable-g.component.ts | 8 +- .../monitoring-form.component-g.css | 31 ++ .../monitoring-form.component-g.html | 124 ++++++ .../monitoring-form.component-g.spec.ts | 25 ++ .../monitoring-form.component-g.ts | 403 ++++++++++++++++++ .../monitoring-form.component.ts | 5 + .../monitoring-properties-g.component.html | 3 +- .../monitoring-properties-g.component.ts | 16 +- .../monitoring-sites.component.html | 10 +- .../monitoring-sites.component.ts | 7 +- .../monitoring-sitesgroups.component.html | 30 +- .../monitoring-sitesgroups.component.ts | 19 +- frontend/app/gnModule.module.ts | 7 +- frontend/app/interfaces/response.ts | 7 + frontend/app/services/config.service.ts | 4 +- frontend/app/services/edit-object.service.ts | 109 +++++ frontend/app/services/sites_group.service.ts | 5 + 28 files changed, 919 insertions(+), 54 deletions(-) create mode 100644 backend/gn_module_monitoring/utils/errors/__init__.py create mode 100644 backend/gn_module_monitoring/utils/errors/errorHandler.py create mode 100644 backend/gn_module_monitoring/utils/strings/__init__.py create mode 100644 backend/gn_module_monitoring/utils/strings/en-gb.json create mode 100644 backend/gn_module_monitoring/utils/strings/strings.py create mode 100644 frontend/app/components/monitoring-form-g/monitoring-form.component-g.css create mode 100644 frontend/app/components/monitoring-form-g/monitoring-form.component-g.html create mode 100644 frontend/app/components/monitoring-form-g/monitoring-form.component-g.spec.ts create mode 100644 frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts create mode 100644 frontend/app/interfaces/response.ts create mode 100644 frontend/app/services/edit-object.service.ts diff --git a/.gitignore b/.gitignore index 98dd43081..9f3b24fa8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ config/monitoring/* frontend/assets/*.jpg *.egg-info +**/contrib # Node .npm node_modules diff --git a/backend/gn_module_monitoring/monitoring/models.py b/backend/gn_module_monitoring/monitoring/models.py index 1aa51c989..aabc5978d 100644 --- a/backend/gn_module_monitoring/monitoring/models.py +++ b/backend/gn_module_monitoring/monitoring/models.py @@ -21,6 +21,47 @@ from geonature.core.gn_monitoring.models import corVisitObserver from gn_module_monitoring.monitoring.queries import Query as MonitoringQuery +import sqlalchemy +from sqlalchemy.orm import class_mapper +from sqlalchemy.ext.declarative import declared_attr + + +class GenericModel: + @declared_attr + def __tablename__(cls): + return cls.__name__.lower() + + @classmethod + def attribute_names(cls): + return [ + prop.key + for prop in class_mapper(cls).iterate_properties + if isinstance(prop, sqlalchemy.orm.ColumnProperty) + ] + + @classmethod + def get_type_fields(cls): + structure_data = {prop.key:type(prop.expression.type).__name__ for prop in class_mapper(cls).iterate_properties + if isinstance(prop, sqlalchemy.orm.ColumnProperty)} + for prop in class_mapper(cls).iterate_properties: + if isinstance(prop, sqlalchemy.orm.RelationshipProperty): + structure_data[prop.key] = "Select" + return structure_data + + @classmethod + def get_only_field_table(cls): + fields_table = [i.name for i in cls.__table__.columns] + structure_data = {prop.key:type(prop.expression.type).__name__ for prop in class_mapper(cls).iterate_properties + if isinstance(prop, sqlalchemy.orm.ColumnProperty) and prop.key in fields_table} + for prop in class_mapper(cls).iterate_properties: + if isinstance(prop, sqlalchemy.orm.RelationshipProperty): + structure_data[prop.key] = "Select" + return structure_data + + # __table_args__ = {'mysql_engine': 'InnoDB'} + # id = DB.Column(Integer, primary_key=True) + + cor_module_type = DB.Table( "cor_module_type", DB.Column( @@ -247,7 +288,7 @@ class TMonitoringSites(TBaseSites): ) @serializable -class TMonitoringSitesGroups(DB.Model): +class TMonitoringSitesGroups(DB.Model,GenericModel): __tablename__ = 't_sites_groups' __table_args__ = {'schema': 'gn_monitoring'} query_class = MonitoringQuery diff --git a/backend/gn_module_monitoring/monitoring/schemas.py b/backend/gn_module_monitoring/monitoring/schemas.py index d42211706..91276d701 100644 --- a/backend/gn_module_monitoring/monitoring/schemas.py +++ b/backend/gn_module_monitoring/monitoring/schemas.py @@ -1,7 +1,7 @@ import json import geojson -from marshmallow import Schema, fields +from marshmallow import Schema, fields, validate from marshmallow_sqlalchemy import SQLAlchemyAutoSchema from pypnnomenclature.schemas import NomenclatureSchema @@ -23,6 +23,10 @@ class PaginationSchema(Schema): class MonitoringSitesGroupsSchema(SQLAlchemyAutoSchema): + + sites_group_name = fields.String( + validate=validate.Length(min=3,error="Length must be greater than 3"),) + class Meta: model = TMonitoringSitesGroups exclude = ("geom_geojson",) diff --git a/backend/gn_module_monitoring/routes/sites_groups.py b/backend/gn_module_monitoring/routes/sites_groups.py index 77de3df5a..991b6f4f6 100644 --- a/backend/gn_module_monitoring/routes/sites_groups.py +++ b/backend/gn_module_monitoring/routes/sites_groups.py @@ -1,5 +1,6 @@ from flask import jsonify, request from geonature.utils.env import db +from gn_module_monitoring.utils.strings.strings import gettext from sqlalchemy import func from werkzeug.datastructures import MultiDict @@ -14,6 +15,9 @@ paginate, sort, ) +from gn_module_monitoring.monitoring.schemas import MonitoringSitesGroupsSchema +from marshmallow import ValidationError +from gn_module_monitoring.utils.errors.errorHandler import InvalidUsage @blueprint.route("/sites_groups", methods=["GET"]) @@ -61,3 +65,41 @@ def get_sites_group_geometries(): result = geojson_query(subquery) return jsonify(result) + + +@blueprint.route("/sites_groups/", methods=["PATCH"]) +def patch(_id): + item_schema = MonitoringSitesGroupsSchema() + item_json = request.get_json() + item = TMonitoringSitesGroups.query.filter_by(id_sites_group=_id).first() + if item: + fields = TMonitoringSitesGroups.attribute_names() + for field in item_json: + if field in (fields): + # getattr(Models.NgBase,field) + setattr(item, field, item_json[field]) + else: + continue + # return {"message": gettext("field_not_valid").format(field,item.__str__())}, 404 + # return InvalidUsage( + # gettext("field_not_valid").format(field, item.__tablename__), + # status_code=404, + # payload=item_json, + # ).to_dict() + else: + item = item_schema.load(item_json) + +# TODO: check why there is no select inside fields + # structure_data = TMonitoringSitesGroups.get_only_field_table() + try: + item_schema.load(item_json) + db.session.add(item) + db.session.commit() + except ValidationError as err: + return InvalidUsage( + gettext("item_not_validated").format(err.messages), status_code=422, payload=item_json + ).to_dict() + except: + return InvalidUsage("Internal Error", status_code=500).to_dict() + + return item_schema.dump(item), 201 diff --git a/backend/gn_module_monitoring/utils/errors/__init__.py b/backend/gn_module_monitoring/utils/errors/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/backend/gn_module_monitoring/utils/errors/errorHandler.py b/backend/gn_module_monitoring/utils/errors/errorHandler.py new file mode 100644 index 000000000..3fed70bf2 --- /dev/null +++ b/backend/gn_module_monitoring/utils/errors/errorHandler.py @@ -0,0 +1,30 @@ +# class APIError(Exception): +# """All custom API Exceptions""" +# pass + + +class InvalidUsage(Exception): + status_code = 400 + + def __init__(self, message, status_code=None, payload=None): + Exception.__init__(self) + self.message = message + if status_code is not None: + self.status_code = status_code + self.payload = payload + + + def to_dict(self): + rv = {} + # rv['payload'] = dict(self.payload or ()) + rv["payload"] = self.payload + rv["message"] = self.message + rv["status_code"] = self.status_code + return (rv,self.status_code) + + +class APIAuthError(Exception): + """Custom Authentication Error Class.""" + + code = 403 + description = "Authentication Error" diff --git a/backend/gn_module_monitoring/utils/strings/__init__.py b/backend/gn_module_monitoring/utils/strings/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/backend/gn_module_monitoring/utils/strings/en-gb.json b/backend/gn_module_monitoring/utils/strings/en-gb.json new file mode 100644 index 000000000..02dc5a53c --- /dev/null +++ b/backend/gn_module_monitoring/utils/strings/en-gb.json @@ -0,0 +1,8 @@ +{ + "item_name_exists": "An item with name '{}' already exists.", + "item_error_inserting": "An error occurred while inserting the item.", + "item_not_found": "An item cannot be found.", + "item_deleted": "Item deleted.", + "item_not_validated" :"Validation fields not pass , message : {}", + "field_not_valid":"The field '{}' from request body is not valid see the model {} '" +} \ No newline at end of file diff --git a/backend/gn_module_monitoring/utils/strings/strings.py b/backend/gn_module_monitoring/utils/strings/strings.py new file mode 100644 index 000000000..b43e719f4 --- /dev/null +++ b/backend/gn_module_monitoring/utils/strings/strings.py @@ -0,0 +1,25 @@ +""" +libs.strings + +By default, uses `en-gb.json` file inside the `strings` top-level folder. + +If language changes, set `libs.strings.default_locale` and run `libs.strings.refresh()`. +""" +import json,os + +default_locale = "en-gb" +cached_strings = {} +dir = os.path.dirname(os.path.realpath(__file__)) +# parent_dir = os.path.abspath(os.path.join(dir, os.pardir)) +def refresh(): + print("Refreshing...") + global cached_strings + with open(os.path.join(dir,f"{default_locale}.json")) as f: + cached_strings = json.load(f) + + +def gettext(name): + return cached_strings[name] + + +refresh() diff --git a/config/monitoring/generic/config.json b/config/monitoring/generic/config.json index f2dafb345..092f10feb 100644 --- a/config/monitoring/generic/config.json +++ b/config/monitoring/generic/config.json @@ -1,9 +1,10 @@ { "tree": { "module": { + "sites_group":{ "site": { "visit": { - "observation": null + "observation": null } } } } diff --git a/frontend/app/components/modules/modules.component.html b/frontend/app/components/modules/modules.component.html index 72863fc15..3e63f83e2 100644 --- a/frontend/app/components/modules/modules.component.html +++ b/frontend/app/components/modules/modules.component.html @@ -14,7 +14,7 @@

{{titleModule}}

{{description}}
-
diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts index 01cafd5bb..812c641b1 100644 --- a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts @@ -179,13 +179,17 @@ export class MonitoringDatatableGComponent implements OnInit { ngOnChanges(changes: SimpleChanges) { console.log("inside ngOnChanges"); console.log("changes", changes); - if (changes["rows"] && this.rows) { + if (changes["rows"] && this.rows && this.rows.length > 0) { this.columns = this._dataTableService.colsTable( this.colsname, this.rows[0] ); } + if (changes["colsname"]) { + this.filters = {}; + } + if (changes["obj"] && this.obj) { this.objectsStatus, (this.rowStatus = this._dataTableService.initObjectsStatus( @@ -196,7 +200,7 @@ export class MonitoringDatatableGComponent implements OnInit { for (const propName of Object.keys(changes)) { const chng = changes[propName]; const cur = chng.currentValue; - const pre = chng.currentValue; + const pre = chng.previousValue; switch (propName) { case "rowStatus": this.setSelected(); diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.css b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.css new file mode 100644 index 000000000..a5c26b9ca --- /dev/null +++ b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.css @@ -0,0 +1,31 @@ +:host ::ng-deep .obj-form { + margin: 0; + margin-bottom: 10px; + padding: 0; +} + +.hide-spinner { + display: none; +} + +.btn-height { + height: 39px; +} + +.float-right { +margin-left: 5px; +} + + +.float-left { + margin-right: 10px; + float: left; +} + +form:invalid { + outline: none; +} + +form.ng-invalid { + border: 0px !important; +} \ No newline at end of file diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.html b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.html new file mode 100644 index 000000000..389e9284b --- /dev/null +++ b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.html @@ -0,0 +1,124 @@ + +

Attention

+

+ + Vous êtes sur le point de supprimer le groupe de site + Description du groupe de site +

+ + +
+ +
+
+ + + + + + + +
+ + + + + + + + +
+ + + + + + +
+
+
+
+
diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.spec.ts b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.spec.ts new file mode 100644 index 000000000..1cfc81be0 --- /dev/null +++ b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MonitoringFormComponent } from './monitoring-form.component'; + +describe('MonitoringFormComponent', () => { + let component: MonitoringFormComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MonitoringFormComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MonitoringFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts new file mode 100644 index 000000000..054ce1b26 --- /dev/null +++ b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts @@ -0,0 +1,403 @@ +import { Component, OnInit, Input, Output, EventEmitter,SimpleChanges, } from "@angular/core"; +import { FormGroup, FormBuilder, Validators } from "@angular/forms"; +import { MonitoringObject } from "../../class/monitoring-object"; +// import { Router } from "@angular/router"; +import { ConfigService } from "../../services/config.service"; +import { DataUtilsService } from "../../services/data-utils.service"; +import { CommonService } from "@geonature_common/service/common.service"; +import { DynamicFormService } from "@geonature_common/form/dynamic-form-generator/dynamic-form.service"; +import { ActivatedRoute } from "@angular/router"; +import { EditObjectService } from "../../services/edit-object.service"; +import { SitesGroupService } from "../../services/sites_group.service"; +import { Router } from "@angular/router"; +import { JsonData } from "../../types/jsondata"; +@Component({ + selector: "pnx-monitoring-form-g", + templateUrl: "./monitoring-form.component-g.html", + styleUrls: ["./monitoring-form.component-g.css"], +}) +export class MonitoringFormComponentG implements OnInit { + @Input() currentUser; + + @Input() objForm: FormGroup; + + // @Input() obj: any; + @Output() objChanged = new EventEmitter(); + + @Input() objectsStatus; + @Output() objectsStatusChange = new EventEmitter(); + + @Input() bEdit: boolean; + @Output() bEditChange = new EventEmitter(); + + @Input() sites: {}; + dataForm:JsonData; + searchSite = ""; + + obj:any; + objFormsDefinition; + + meta: {}; + + public bSaveSpinner = false; + public bSaveAndAddChildrenSpinner = false; + public bDeleteSpinner = false; + public bDeleteModal = false; + public bChainInput = false; + public bAddChildren = false; + public chainShow = []; + + public queryParams = {}; + + constructor( + private _formBuilder: FormBuilder, + private _route: ActivatedRoute, + private _configService: ConfigService, + private _commonService: CommonService, + private _dataUtilsService: DataUtilsService, + private _dynformService: DynamicFormService, + private _editService: EditObjectService, + private _siteGpService: SitesGroupService, + private _router: Router + ) {} + + ngOnInit() { + // console.log(this.obj); + // this.obj.moduleCode = "generic"; + // this.obj.objectType = "sites_group"; + console.log(this.obj); + + this._editService.currentData.subscribe(dataToEdit => { + this.obj = dataToEdit + console.log("inside subscribe FORM",this.obj) + // this.obj.moduleCode = "generic"; + // this.obj.objectType = "sites_group"; + this.obj.bIsInitialized = true + this._configService + .init(this.obj.moduleCode) + .pipe() + .subscribe(() => { + // return this._route.queryParamMap; + // }) + // .subscribe((queryParams) => { + this.queryParams = this._route.snapshot.queryParams || {}; + this.bChainInput = this._configService.frontendParams()["bChainInput"]; + + const schema = this._configService.schema( + this.obj.moduleCode, + this.obj.objectType + ); + console.log(schema); + this.obj[this.obj.moduleCode] = schema + // const schema = this.obj.schema(); + + // init objFormsDefinition + + // meta pour les parametres dynamiques + // ici pour avoir acces aux nomenclatures + this.meta = { + // nomenclatures: this._dataUtilsService.getDataUtil('nomenclature'), + // dataset: this._dataUtilsService.getDataUtil('dataset'), + // id_role: this.currentUser.id_role, + bChainInput: this.bChainInput, + parents: this.obj.parents, + }; + + console.log(this.meta); + this.objFormsDefinition = this._dynformService + .formDefinitionsdictToArray(schema, this.meta) + .filter((formDef) => formDef.type_widget) + .sort((a, b) => { + // medias à la fin + return a.attribut_name === "medias" + ? +1 + : b.attribut_name === "medias" + ? -1 + : 0; + }); + + // display_form pour customiser l'ordre dans le formulaire + // les éléments de display form sont placé en haut dans l'ordre du tableau + // tous les éléments non cachés restent affichés + + let displayProperties = [ + ...(this._configService.configModuleObjectParam( + this.obj.moduleCode, + this.obj.objectType, + "display_properties" + ) || []), + ]; + if (displayProperties && displayProperties.length) { + displayProperties.reverse(); + this.objFormsDefinition.sort((a, b) => { + let indexA = displayProperties.findIndex( + (e) => e == a.attribut_name + ); + let indexB = displayProperties.findIndex( + (e) => e == b.attribut_name + ); + return indexB - indexA; + }); + } + + // champs patch pour simuler un changement de valeur et déclencher le recalcul des propriété + // par exemple quand bChainInput change + this.objForm.addControl("patch_update", this._formBuilder.control(0)); + + // this._configService.configModuleObject(this.obj.moduleCode, this.obj.objectType); + // set geometry + // if (this.obj.config["geometry_type"]) { + // this.objForm.addControl( + // "geometry", + // this._formBuilder.control("", Validators.required) + // ); + // } + + // pour donner la valeur de idParent + + this.initForm(); + }); + }) + + } + + + /** pour réutiliser des paramètres déjà saisis */ + keepDefinitions() { + return this.objFormsDefinition.filter((def) => + this.obj.configParam("keep").includes(def.attribut_name) + ); + } + + setQueryParams() { + // par le biais des parametre query de route on donne l'id du ou des parents + // permet d'avoir un 'tree' ou un objet est sur plusieurs branches + // on attend des ids d'où test avec parseInt + for (const key of Object.keys(this.queryParams)) { + const strToInt = parseInt(this.queryParams[key]); + if (strToInt != NaN) { + this.obj.properties[key] = strToInt; + } + } + } + + /** initialise le formulaire quand le formulaire est prêt ou l'object est prêt */ + initForm() { + if (!(this.objForm && this.obj.bIsInitialized)) { + return; + } + + this.setQueryParams(); + console.log("Init Form" , this.obj) + // pour donner la valeur de l'objet au formulaire + this._editService.formValues(this.obj).subscribe((formValue) => { + console.log(formValue) + this.objForm.patchValue(formValue); + this.setDefaultFormValue(); + this.dataForm = formValue + // reset geom ? + }); + } + + keepNames() { + return this.obj.configParam("keep") || []; + } + + resetObjForm() { + // quand on enchaine les relevés + const chainShow = this.obj.configParam("chain_show"); + if (chainShow) { + this.chainShow.push( + chainShow.map((key) => this.obj.resolvedProperties[key]) + ); + this.chainShow.push(this.obj.resolvedProperties); + } + + // les valeur que l'on garde d'une saisie à l'autre + const keep = {}; + for (const key of this.keepNames()) { + keep[key] = this.obj.properties[key]; + } + + // nouvel object + this.obj = new MonitoringObject( + this.obj.moduleCode, + this.obj.objectType, + null, + this.obj.monitoringObjectService() + ); + this.obj.init({}); + + this.obj.properties[this.obj.configParam("id_field_Name")] = null; + + // pq get ????? + // this.obj.get(0).subscribe(() => { + this.obj.bIsInitialized = true; + for (const key of this.keepNames()) { + this.obj.properties[key] = keep[key]; + } + + this.objChanged.emit(this.obj); + this.objForm.patchValue({ geometry: null }); + this.initForm(); + // }); + } + + /** Pour donner des valeurs par defaut si la valeur n'est pas définie + * id_digitiser => current_user.id_role + * id_inventor => current_user.id_role + * date => today + */ + setDefaultFormValue() { + const value = this.objForm.value; + const date = new Date(); + const defaultValue = { + // id_digitiser: value["id_digitiser"] || this.currentUser.id_role, + // id_inventor: value["id_inventor"] || this.currentUser.id_role, + first_use_date: value["first_use_date"] || { + year: date.getUTCFullYear(), + month: date.getUTCMonth() + 1, + day: date.getUTCDate(), + }, + }; + this.objForm.patchValue(defaultValue); + } + + /** + * TODO faire des fonctions dans monitoring objet (ou moniotring objet service pour naviguer + */ + + /** + * Valider et renseigner les enfants + */ + navigateToAddChildren() { + this.bEditChange.emit(false); + this.obj.navigateToAddChildren(); + } + + /** + * Valider et aller à la page de l'objet + */ + navigateToDetail(id,moduleCode,objectType,queryParams) { + // patch bug navigation + this._router.navigate( + [ + "monitorings", + objectType, + id, + ].filter((s) => !!s), + { + queryParams, + } + ); + this.bEditChange.emit(false); + } + + /** + * Valider et aller à la page de l'objet + */ + navigateToParent() { + this.bEditChange.emit(false); // patch bug navigation + // this.obj.navigateToParent(); + } + + msgToaster(action) { + // return `${action} ${this.obj.labelDu()} ${this.obj.description()} effectuée`.trim(); + return `${action} effectuée`.trim(); + } + + /** TODO améliorer site etc.. */ + onSubmit() { + const action = this.obj.id + // ? this.obj.patch(this.objForm.value) + // : this.obj.post(this.objForm.value); + ? this._siteGpService.patchGroupSite(this.obj.id,this.dataForm) + : this.obj.post(this.objForm.value); + const actionLabel = this.obj.id ? "Modification" : "Création"; + action.subscribe((objData) => { + this._commonService.regularToaster( + "success", + this.msgToaster(actionLabel) + ); + this.bSaveSpinner = this.bSaveAndAddChildrenSpinner = false; + this.objChanged.emit(this.obj); + + /** si c'est un module : reset de la config */ + if (this.obj.objectType === "module") { + this._configService.loadConfig(this.obj.moduleCode).subscribe(); + } + + if (this.bChainInput) { + this.resetObjForm(); + } else if (this.bAddChildren) { + this.navigateToAddChildren(); + } else { + if (this._configService.configModuleObjectParam(this.obj.moduleCode,this.obj.objectType,"redirect_to_parent")) { + this.navigateToParent(); + } else { + this.navigateToDetail(this.obj.id,this.obj.moduleCode,this.obj.objectType,this.queryParams); + } + } + }); + } + + onCancelEdit() { + if (this.obj.id) { + this.bEditChange.emit(false); + } else { + this.navigateToParent(); + } + } + + onDelete() { + this.bDeleteSpinner = true; + this._commonService.regularToaster("info", this.msgToaster("Suppression")); + + this.obj.delete().subscribe((objData) => { + this.bDeleteSpinner = this.bDeleteModal = false; + this.obj.deleted = true; + this.objChanged.emit(this.obj); + + setTimeout(() => { + this.navigateToParent(); + }, 100); + }); + } + + onObjFormValueChange(event) { + let {id_module,medias, ...rest} = this.objForm.value; + this.dataForm = rest + console.log(this.dataForm) + const change = this._configService.change(this.obj.moduleCode ,this.obj.objectType ); + if (!change) { + return; + } + setTimeout(() => { + change({ objForm: this.objForm, meta: this.meta }); + }, 100); + } + + procesPatchUpdateForm() { + this.objForm.patchValue({ + patch_update: this.objForm.value.patch_update + 1, + }); + } + + /** bChainInput gardé dans config service */ + bChainInputChanged() { + for (const formDef of this.objFormsDefinition) { + formDef.meta.bChainInput = this.bChainInput; + } + this._configService.setFrontendParams("bChainInput", this.bChainInput); + // patch pour recalculers + this.procesPatchUpdateForm(); + } + + ngOnChanges(changes: SimpleChanges) { + console.log("inside ngOnChanges"); + console.log("changes", changes); + if (changes["obj"] && this.obj) { + console.log(this.obj) + } + } +} diff --git a/frontend/app/components/monitoring-form/monitoring-form.component.ts b/frontend/app/components/monitoring-form/monitoring-form.component.ts index 3e0ae5634..2e5102e62 100644 --- a/frontend/app/components/monitoring-form/monitoring-form.component.ts +++ b/frontend/app/components/monitoring-form/monitoring-form.component.ts @@ -55,6 +55,9 @@ export class MonitoringFormComponent implements OnInit { ) {} ngOnInit() { + // console.log(this.obj) + // this.obj.moduleCode = "generic" + // this.obj.objectType = "sites_group" this._configService .init(this.obj.moduleCode) .pipe() @@ -65,6 +68,8 @@ export class MonitoringFormComponent implements OnInit { this.queryParams = this._route.snapshot.queryParams || {}; this.bChainInput = this._configService.frontendParams()['bChainInput']; const schema = this.obj.schema(); + + console.log("Init Form this.obj.schema()",schema ) // init objFormsDefinition // meta pour les parametres dynamiques diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html index d8701bc3b..ce616043d 100644 --- a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html @@ -105,7 +105,8 @@ Éditer {{ (obj.template['label_art_def'] || "") }} --> - diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts index c9967b46c..2b97ae183 100644 --- a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts @@ -7,10 +7,9 @@ import { SimpleChanges, } from "@angular/core"; import { FormControl } from "@angular/forms"; -import { - extendedDetailsSiteGroup, -} from "../../class/monitoring-sites-group"; +import { extendedDetailsSiteGroup } from "../../class/monitoring-sites-group"; import { ISitesGroup } from "../../interfaces/geom"; +import { EditObjectService } from "../../services/edit-object.service"; @Component({ selector: "pnx-monitoring-properties-g", @@ -34,7 +33,7 @@ export class MonitoringPropertiesGComponent implements OnInit { bUpdateSyntheseSpinner = false; public modalReference; - constructor() {} + constructor(private _editService: EditObjectService) {} ngOnInit() { console.log("selectedObj", this.selectedObj); @@ -43,6 +42,15 @@ export class MonitoringPropertiesGComponent implements OnInit { onEditClick() { this.bEditChange.emit(true); + console.log("edit"); + console.log("obj inside PROPERTIES", this.selectedObj); + let id_object = this.getId() + this.selectedObj["id"] = this.selectedObj[id_object[0]] + this._editService.changeDataSub(this.selectedObj); + } + + getId(){ + return Object.keys(this.selectedObj).filter(k => k.startsWith('id')) } // ngOnChanges(changes: SimpleChanges) { diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.html b/frontend/app/components/monitoring-sites/monitoring-sites.component.html index ff1c72acf..2322122e5 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.html +++ b/frontend/app/components/monitoring-sites/monitoring-sites.component.html @@ -1,6 +1,12 @@ - + - + params["id"] as number), diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index 72c88e8fc..69abd880b 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -1,22 +1,12 @@ - - - -
- +
diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index f37739abd..33b78ab47 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -1,21 +1,13 @@ import { Component, OnInit, Input } from "@angular/core"; -import { ConfigService } from "../../services/config.service"; -import { MapService } from "@geonature_common/map/map.service"; -import { Subscription } from "rxjs"; import { SitesGroupService } from "../../services/sites_group.service"; import { columnNameSiteGroup } from "../../class/monitoring-sites-group"; import { IPaginated, IPage } from "../../interfaces/page"; import { Router, - Event, - NavigationStart, - NavigationEnd, - NavigationError, ActivatedRoute, } from "@angular/router"; import { columnNameSite } from "../../class/monitoring-site"; import { ISite, ISitesGroup } from "../../interfaces/geom"; -import { SitesService } from "../../services/sites.service"; import { GeoJSONService } from "../../services/geojson.service"; import { MonitoringGeomComponent } from "../../class/monitoring-geom-component"; import { setPopup } from "../../functions/popup"; @@ -43,20 +35,13 @@ export class MonitoringSitesGroupsComponent @Input() colsname; @Input() obj; - filters = {}; - displayDetails: boolean = false; - path: string; - currentRoute: string = ""; - id: string | null; constructor( private _sites_group_service: SitesGroupService, - private _sites_service: SitesService, public geojsonService: GeoJSONService, - private _configService: ConfigService, private router: Router, - private _Activatedroute: ActivatedRoute // private _routingService: RoutingService - ) { + private _Activatedroute: ActivatedRoute, // private _routingService: RoutingService + ) { super(); this.getAllItemsCallback = this.getSitesGroups; } diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index aef805c79..55de96b25 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -40,7 +40,8 @@ import { SitesService } from "./services/sites.service"; import { GeoJSONService } from "./services/geojson.service"; import { MonitoringSitesComponent } from "./components/monitoring-sites/monitoring-sites.component"; import { MonitoringMapListComponent } from "./components/monitoring-map-list/monitoring-map-list.component"; -// import { RoutingService } from "./services/routing.service"; +import { MonitoringFormComponentG } from "./components/monitoring-form-g/monitoring-form.component-g"; +import { EditObjectService } from "./services/edit-object.service"; // my module routing const routes: Routes = [ @@ -63,7 +64,7 @@ const routes: Routes = [ component: MonitoringObjectComponent, }, { - path: "sites_groups", + path: "sites_group", component: MonitoringMapListComponent, children: [ { @@ -95,6 +96,7 @@ const routes: Routes = [ MonitoringSitesComponent, MonitoringDatatableGComponent, MonitoringPropertiesGComponent, + MonitoringFormComponentG ], imports: [ GN2CommonModule, @@ -122,6 +124,7 @@ const routes: Routes = [ SitesGroupService, SitesService, GeoJSONService, + EditObjectService // RoutingService ], bootstrap: [ModulesComponent], diff --git a/frontend/app/interfaces/response.ts b/frontend/app/interfaces/response.ts new file mode 100644 index 000000000..4cb97ddef --- /dev/null +++ b/frontend/app/interfaces/response.ts @@ -0,0 +1,7 @@ +import { JsonData } from "../types/jsondata" + +export interface ResponseUpdated { + message:string + payload:JsonData + status_code:number +} \ No newline at end of file diff --git a/frontend/app/services/config.service.ts b/frontend/app/services/config.service.ts index d37243b66..6776e3297 100644 --- a/frontend/app/services/config.service.ts +++ b/frontend/app/services/config.service.ts @@ -31,6 +31,7 @@ export class ConfigService { } loadConfig(moduleCode) { + console.log(moduleCode) const urlConfig = moduleCode === 'generic' ? `${this.backendModuleUrl()}/config` @@ -128,8 +129,9 @@ export class ConfigService { schema(moduleCode, objectType, typeSchema = 'all'): Object { moduleCode = moduleCode || 'generic'; + console.log("moduleCode inside config.service",moduleCode) const configObject = this._config[moduleCode][objectType]; - + console.log("configObject inside config.service",configObject) // gerer quand les paramètres ont un fonction comme valeur for (const typeSchema of ['generic', 'specific']) { diff --git a/frontend/app/services/edit-object.service.ts b/frontend/app/services/edit-object.service.ts new file mode 100644 index 000000000..5c94c6108 --- /dev/null +++ b/frontend/app/services/edit-object.service.ts @@ -0,0 +1,109 @@ +import { Injectable } from "@angular/core"; +import { BehaviorSubject, Observable, of, forkJoin } from "rxjs"; +import { mergeMap, concatMap } from "rxjs/operators"; + +import { JsonData } from "../types/jsondata"; +import { ConfigService } from "./config.service"; + +import { Utils } from "../utils/utils"; +import { DataUtilsService } from "./data-utils.service"; + +@Injectable() +export class EditObjectService { + data: JsonData = {}; + private dataSub = new BehaviorSubject(this.data); + currentData = this.dataSub.asObservable(); + private _config; + properties: JsonData; + moduleCode:string; + objecType:string; + + constructor( + private _configService: ConfigService, + private _dataUtilsService: DataUtilsService + ) {} + + changeDataSub(newDat: JsonData) { + this.properties = newDat; + newDat.moduleCode = "generic"; + newDat.objectType = "sites_group"; + this.moduleCode= "generic"; + this.objecType= "sites_group" + this.dataSub.next(newDat) + + } + + + + formValues(obj): Observable { + const properties = Utils.copy(this.properties); + const observables = {}; + const schema = obj[this.moduleCode]; + for (const attribut_name of Object.keys(schema)) { + if (attribut_name == "id_module" || attribut_name =="medias" ){ + continue; + } + const elem = schema[attribut_name]; + if (!elem.type_widget) { + continue; + } + observables[attribut_name] = this.toForm(elem, properties[attribut_name]); + } + console.log(observables) + return forkJoin(observables).pipe( + concatMap((formValues_in) => { + const formValues = Utils.copy(formValues_in); + // geometry + // if (this.config["geometry_type"]) { + // formValues["geometry"] = this.geometry; // copy??? + // } + return of(formValues); + }) + ); + } + + toForm(elem, val): Observable { + let x = val; + // valeur par default depuis la config schema + x = [undefined, null].includes(x) ? elem.value || null : x; + + switch (elem.type_widget) { + case "date": { + const date = new Date(x); + x = x + ? { + year: date.getUTCFullYear(), + month: date.getUTCMonth() + 1, + day: date.getUTCDate(), + } + : null; + break; + } + case "observers": { + x = !(x instanceof Array) ? [x] : x; + break; + } + case "taxonomy": { + x = x ? this._dataUtilsService.getUtil("taxonomy", x, "all") : null; + break; + } + } + if ( + elem.type_util === "nomenclature" && + Utils.isObject(x) && + x.code_nomenclature_type && + x.cd_nomenclature + ) { + x = this._dataUtilsService + .getNomenclature(x.code_nomenclature_type, x.cd_nomenclature) + .pipe( + mergeMap((nomenclature) => { + return of(nomenclature["id_nomenclature"]); + }) + ); + } + + x = x instanceof Observable ? x : of(x); + return x; + } +} diff --git a/frontend/app/services/sites_group.service.ts b/frontend/app/services/sites_group.service.ts index f0f97bf37..4b94c90df 100644 --- a/frontend/app/services/sites_group.service.ts +++ b/frontend/app/services/sites_group.service.ts @@ -6,6 +6,7 @@ import { CacheService } from "./cache.service"; import { IGeomService, ISitesGroup, ISite } from "../interfaces/geom"; import { IPaginated } from "../interfaces/page"; import { JsonData } from "../types/jsondata"; +import { ResponseUpdated } from "../interfaces/response"; @Injectable() export class SitesGroupService implements IGeomService { constructor(private _cacheService: CacheService) {} @@ -54,4 +55,8 @@ export class SitesGroupService implements IGeomService { } ); } + + patchGroupSite(id:number,updatedData:JsonData):Observable{ + return this._cacheService.request("patch",`sites_groups/${id}`,{postData : updatedData}) + } } From 6efe45f885c290c7274236cab55bcf881e91eebd Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Wed, 1 Feb 2023 15:52:00 +0100 Subject: [PATCH 26/44] feat: edit sitegroups Improving route 'patch' Adding reload properties when sitegroups is updated Refactoring EditService for more readability Reviewed-by: andriacap [Ref_ticket]: #4 --- .../gn_module_monitoring/monitoring/models.py | 23 +++++++- .../monitoring/schemas.py | 13 ++++- backend/gn_module_monitoring/routes/site.py | 6 +- .../routes/sites_groups.py | 15 +---- config/monitoring/generic/sites_group.json | 5 -- .../monitoring-datatable-g.component.ts | 1 + .../monitoring-form.component-g.ts | 15 +++-- .../monitoring-properties-g.component.ts | 8 +-- .../monitoring-sites.component.ts | 9 ++- .../monitoring-sitesgroups.component.ts | 1 - frontend/app/interfaces/geom.ts | 1 + frontend/app/services/edit-object.service.ts | 57 +------------------ 12 files changed, 62 insertions(+), 92 deletions(-) diff --git a/backend/gn_module_monitoring/monitoring/models.py b/backend/gn_module_monitoring/monitoring/models.py index aabc5978d..36963fe07 100644 --- a/backend/gn_module_monitoring/monitoring/models.py +++ b/backend/gn_module_monitoring/monitoring/models.py @@ -31,6 +31,27 @@ class GenericModel: def __tablename__(cls): return cls.__name__.lower() + @classmethod + def set_id(cls) -> None: + pk_string = class_mapper(cls).primary_key[0].name + if hasattr(cls,"id_g") ==False: + pk_value= getattr(cls,pk_string) + setattr(cls,"id_g",pk_value) + + @classmethod + def get_id(cls) -> None: + pk_string = class_mapper(cls).primary_key[0].name + # print('======= ==>', pk_string) + if hasattr(cls,"id_g") ==False: + pk_value= getattr(cls,pk_string) + setattr(cls,"id_g",pk_value) + return pk_string + + @classmethod + def find_by_id(cls, _id: int) -> "GenericModel": + cls.set_id() + return cls.query.get_or_404(_id) + @classmethod def attribute_names(cls): return [ @@ -94,7 +115,7 @@ def get_only_field_table(cls): @serializable -class BibTypeSite(DB.Model): +class BibTypeSite(DB.Model,GenericModel): __tablename__ = "bib_type_site" __table_args__ = {"schema": "gn_monitoring"} query_class = MonitoringQuery diff --git a/backend/gn_module_monitoring/monitoring/schemas.py b/backend/gn_module_monitoring/monitoring/schemas.py index 91276d701..2bd8d6038 100644 --- a/backend/gn_module_monitoring/monitoring/schemas.py +++ b/backend/gn_module_monitoring/monitoring/schemas.py @@ -1,9 +1,11 @@ import json import geojson -from marshmallow import Schema, fields, validate +from geonature.utils.env import MA +from marshmallow import Schema, fields, validate, pre_load from marshmallow_sqlalchemy import SQLAlchemyAutoSchema from pypnnomenclature.schemas import NomenclatureSchema +from geonature.core.gn_commons.schemas import MediaSchema from gn_module_monitoring.monitoring.models import ( BibTypeSite, @@ -22,7 +24,7 @@ class PaginationSchema(Schema): return PaginationSchema -class MonitoringSitesGroupsSchema(SQLAlchemyAutoSchema): +class MonitoringSitesGroupsSchema(MA.SQLAlchemyAutoSchema): sites_group_name = fields.String( validate=validate.Length(min=3,error="Length must be greater than 3"),) @@ -31,16 +33,21 @@ class Meta: model = TMonitoringSitesGroups exclude = ("geom_geojson",) - + medias = MA.Nested(MediaSchema) + pk = fields.Method("set_pk",dump_only=True) geometry = fields.Method("serialize_geojson", dump_only=True) # properties = fields.Method("group_properties_geojson") # def group_properties_geojson(self, obj): # return {field: getattr(obj,field) for field in self.fields.keys() if field not in ("geometry","properties")} + def set_pk(self,obj): + return self.Meta.model.get_id() + def serialize_geojson(self, obj): if obj.geom_geojson is not None: return json.loads(obj.geom_geojson) + class MonitoringSitesSchema(SQLAlchemyAutoSchema): diff --git a/backend/gn_module_monitoring/routes/site.py b/backend/gn_module_monitoring/routes/site.py index b4c8cc673..9ea95a045 100644 --- a/backend/gn_module_monitoring/routes/site.py +++ b/backend/gn_module_monitoring/routes/site.py @@ -36,8 +36,10 @@ def get_types_site(): @blueprint.route("/sites/types/", methods=["GET"]) def get_type_site_by_id(id_type_site): - query = BibTypeSite.query.filter_by(id_nomenclature_type_site=id_type_site) - res = query.first() + # query = BibTypeSite.query.filter_by(id_nomenclature_type_site=id_type_site) + # res = query.first() + # res2 = BibTypeSite.find_by_id() + res = BibTypeSite.find_by_id(id_type_site) schema = BibTypeSiteSchema() return schema.dump(res) diff --git a/backend/gn_module_monitoring/routes/sites_groups.py b/backend/gn_module_monitoring/routes/sites_groups.py index 991b6f4f6..fa38b2359 100644 --- a/backend/gn_module_monitoring/routes/sites_groups.py +++ b/backend/gn_module_monitoring/routes/sites_groups.py @@ -41,8 +41,8 @@ def get_sites_groups(): @blueprint.route("/sites_groups/", methods=["GET"]) def get_sites_group_by_id(id_sites_group: int): schema = MonitoringSitesGroupsSchema() - result = TMonitoringSitesGroups.query.get_or_404(id_sites_group) - + # result = TMonitoringSitesGroups.query.get_or_404(id_sites_group) + result = TMonitoringSitesGroups.find_by_id(id_sites_group) return jsonify(schema.dump(result)) @@ -71,7 +71,7 @@ def get_sites_group_geometries(): def patch(_id): item_schema = MonitoringSitesGroupsSchema() item_json = request.get_json() - item = TMonitoringSitesGroups.query.filter_by(id_sites_group=_id).first() + item = TMonitoringSitesGroups.find_by_id(_id) if item: fields = TMonitoringSitesGroups.attribute_names() for field in item_json: @@ -80,17 +80,8 @@ def patch(_id): setattr(item, field, item_json[field]) else: continue - # return {"message": gettext("field_not_valid").format(field,item.__str__())}, 404 - # return InvalidUsage( - # gettext("field_not_valid").format(field, item.__tablename__), - # status_code=404, - # payload=item_json, - # ).to_dict() else: item = item_schema.load(item_json) - -# TODO: check why there is no select inside fields - # structure_data = TMonitoringSitesGroups.get_only_field_table() try: item_schema.load(item_json) db.session.add(item) diff --git a/config/monitoring/generic/sites_group.json b/config/monitoring/generic/sites_group.json index fc7c96d57..d56dbff39 100644 --- a/config/monitoring/generic/sites_group.json +++ b/config/monitoring/generic/sites_group.json @@ -23,11 +23,6 @@ "attribut_label": "Id site", "hidden": true }, - "id_module": { - "type_widget": "text", - "attribut_label": "ID Module", - "hidden": true - }, "sites_group_name": { "type_widget": "text", "attribut_label": "Nom", diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts index 812c641b1..caebd21d5 100644 --- a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts @@ -213,6 +213,7 @@ export class MonitoringDatatableGComponent implements OnInit { } navigateToDetail(row) { console.log("Inside navigateToDetail:", row); + row["id"] = row.pk this.onDetailsRow.emit(row); } } diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts index 054ce1b26..55f2b7574 100644 --- a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts +++ b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts @@ -22,7 +22,7 @@ export class MonitoringFormComponentG implements OnInit { @Input() objForm: FormGroup; // @Input() obj: any; - @Output() objChanged = new EventEmitter(); + @Output() objChanged = new EventEmitter(); @Input() objectsStatus; @Output() objectsStatusChange = new EventEmitter(); @@ -278,7 +278,7 @@ export class MonitoringFormComponentG implements OnInit { /** * Valider et aller à la page de l'objet */ - navigateToDetail(id,moduleCode,objectType,queryParams) { + navigateToDetail(id,objectType,queryParams) { // patch bug navigation this._router.navigate( [ @@ -308,10 +308,12 @@ export class MonitoringFormComponentG implements OnInit { /** TODO améliorer site etc.. */ onSubmit() { + console.log(this.obj) + const {patch_update, ...sendValue} = this.dataForm const action = this.obj.id // ? this.obj.patch(this.objForm.value) // : this.obj.post(this.objForm.value); - ? this._siteGpService.patchGroupSite(this.obj.id,this.dataForm) + ? this._siteGpService.patchGroupSite(this.obj.id,sendValue) : this.obj.post(this.objForm.value); const actionLabel = this.obj.id ? "Modification" : "Création"; action.subscribe((objData) => { @@ -335,7 +337,7 @@ export class MonitoringFormComponentG implements OnInit { if (this._configService.configModuleObjectParam(this.obj.moduleCode,this.obj.objectType,"redirect_to_parent")) { this.navigateToParent(); } else { - this.navigateToDetail(this.obj.id,this.obj.moduleCode,this.obj.objectType,this.queryParams); + this.navigateToDetail(this.obj.id,this.obj.objectType,this.queryParams); } } }); @@ -365,8 +367,9 @@ export class MonitoringFormComponentG implements OnInit { } onObjFormValueChange(event) { - let {id_module,medias, ...rest} = this.objForm.value; - this.dataForm = rest + // let {id_module,medias, ...rest} = this.objForm.value; + // this.dataForm = rest + this.dataForm = this.objForm.value console.log(this.dataForm) const change = this._configService.change(this.obj.moduleCode ,this.obj.objectType ); if (!change) { diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts index 2b97ae183..dc577ae1f 100644 --- a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts @@ -44,15 +44,9 @@ export class MonitoringPropertiesGComponent implements OnInit { this.bEditChange.emit(true); console.log("edit"); console.log("obj inside PROPERTIES", this.selectedObj); - let id_object = this.getId() - this.selectedObj["id"] = this.selectedObj[id_object[0]] + this.selectedObj["id"] = this.selectedObj[this.selectedObj.pk] this._editService.changeDataSub(this.selectedObj); } - - getId(){ - return Object.keys(this.selectedObj).filter(k => k.startsWith('id')) - } - // ngOnChanges(changes: SimpleChanges) { // console.log("inside ngOnChanges"); // console.log("changes", changes); diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts index 98923f755..486dd5932 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts +++ b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts @@ -46,6 +46,10 @@ export class MonitoringSitesComponent ngOnInit() { this.objForm = this._formBuilder.group({}); + this.initSite() + } + + initSite(){ this._Activatedroute.params .pipe( map((params) => params["id"] as number), @@ -81,7 +85,6 @@ export class MonitoringSitesComponent } ); } - ngOnDestroy() { this._geojsonService.removeFeatureGroup( this._geojsonService.sitesFeatureGroup @@ -122,4 +125,8 @@ export class MonitoringSitesComponent } onSelect($event) {} + + onObjChanged($event) { + this.initSite() + } } diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 33b78ab47..728f3255c 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -87,7 +87,6 @@ export class MonitoringSitesGroupsComponent seeDetails($event) { // TODO: routerLink - console.log("seeDetails"); this.router.navigate([$event.id_sites_group], { relativeTo: this._Activatedroute, }); diff --git a/frontend/app/interfaces/geom.ts b/frontend/app/interfaces/geom.ts index 6cdcc90f9..b3382c197 100644 --- a/frontend/app/interfaces/geom.ts +++ b/frontend/app/interfaces/geom.ts @@ -9,6 +9,7 @@ export interface IGeomObject { } export interface ISitesGroup extends IGeomObject { + pk:number; comments?: string; id_sites_group: number; nb_sites: number; diff --git a/frontend/app/services/edit-object.service.ts b/frontend/app/services/edit-object.service.ts index 5c94c6108..698086095 100644 --- a/frontend/app/services/edit-object.service.ts +++ b/frontend/app/services/edit-object.service.ts @@ -3,24 +3,21 @@ import { BehaviorSubject, Observable, of, forkJoin } from "rxjs"; import { mergeMap, concatMap } from "rxjs/operators"; import { JsonData } from "../types/jsondata"; -import { ConfigService } from "./config.service"; import { Utils } from "../utils/utils"; -import { DataUtilsService } from "./data-utils.service"; +import { MonitoringObjectService } from "./monitoring-object.service"; @Injectable() export class EditObjectService { data: JsonData = {}; private dataSub = new BehaviorSubject(this.data); currentData = this.dataSub.asObservable(); - private _config; properties: JsonData; moduleCode:string; objecType:string; constructor( - private _configService: ConfigService, - private _dataUtilsService: DataUtilsService + private _objService:MonitoringObjectService ) {} changeDataSub(newDat: JsonData) { @@ -40,14 +37,11 @@ export class EditObjectService { const observables = {}; const schema = obj[this.moduleCode]; for (const attribut_name of Object.keys(schema)) { - if (attribut_name == "id_module" || attribut_name =="medias" ){ - continue; - } const elem = schema[attribut_name]; if (!elem.type_widget) { continue; } - observables[attribut_name] = this.toForm(elem, properties[attribut_name]); + observables[attribut_name] = this._objService.toForm(elem, properties[attribut_name]); } console.log(observables) return forkJoin(observables).pipe( @@ -61,49 +55,4 @@ export class EditObjectService { }) ); } - - toForm(elem, val): Observable { - let x = val; - // valeur par default depuis la config schema - x = [undefined, null].includes(x) ? elem.value || null : x; - - switch (elem.type_widget) { - case "date": { - const date = new Date(x); - x = x - ? { - year: date.getUTCFullYear(), - month: date.getUTCMonth() + 1, - day: date.getUTCDate(), - } - : null; - break; - } - case "observers": { - x = !(x instanceof Array) ? [x] : x; - break; - } - case "taxonomy": { - x = x ? this._dataUtilsService.getUtil("taxonomy", x, "all") : null; - break; - } - } - if ( - elem.type_util === "nomenclature" && - Utils.isObject(x) && - x.code_nomenclature_type && - x.cd_nomenclature - ) { - x = this._dataUtilsService - .getNomenclature(x.code_nomenclature_type, x.cd_nomenclature) - .pipe( - mergeMap((nomenclature) => { - return of(nomenclature["id_nomenclature"]); - }) - ); - } - - x = x instanceof Observable ? x : of(x); - return x; - } } From 36e9434df1669e0bc08bd1c390fc0633e7efcf4a Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Wed, 1 Feb 2023 17:23:04 +0100 Subject: [PATCH 27/44] feat: improve edit Add method to define objectType according to service used (site or gpsite) Rewied-by: andriacap [Refs_ticket]: #4 --- .../monitoring-datatable-g.component.html | 3 +- .../monitoring-datatable-g.component.ts | 28 +++++++++---------- .../monitoring-properties-g.component.html | 2 +- .../monitoring-properties-g.component.ts | 2 +- .../monitoring-sites.component.html | 18 ++++++++---- .../monitoring-sites.component.ts | 4 +++ .../monitoring-sitesgroups.component.html | 2 ++ .../monitoring-sitesgroups.component.ts | 11 +++++++- frontend/app/services/data-table.service.ts | 24 ++++++++++++++-- frontend/app/services/sites.service.ts | 8 ++++++ frontend/app/services/sites_group.service.ts | 8 ++++++ 11 files changed, 82 insertions(+), 28 deletions(-) diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html index cfc29c460..17e0a03ed 100644 --- a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.html @@ -21,8 +21,7 @@ class="btn btn-success float-right" (click)="navigateToAddChildren(null, null)" > - Ajouter un nouveau groupe de - site + Ajouter {{objectType}} ; @Output() rowStatusChange = new EventEmitter(); @@ -57,7 +49,6 @@ export class MonitoringDatatableGComponent implements OnInit { @Output() onDetailsRow = new EventEmitter(); private filterSubject: Subject = new Subject(); - private subscription: any; displayFilter: boolean = false; objectsStatus: ItemsObjectTable; @@ -81,6 +72,11 @@ export class MonitoringDatatableGComponent implements OnInit { initDatatable() { console.log("Inside initDatatable"); console.log("this.rows", this.rows); + + // IF prefered observable compare to ngOnChanges uncomment this: + // this._dataTableService.currentCols.subscribe(newCols => { this.columns = newCols }) + + this.filters = {}; this.filterSubject.pipe(debounceTime(500)).subscribe(() => { this.filter(); @@ -179,6 +175,8 @@ export class MonitoringDatatableGComponent implements OnInit { ngOnChanges(changes: SimpleChanges) { console.log("inside ngOnChanges"); console.log("changes", changes); + + // IF prefered ngOnChanges compare to observable uncomment this: if (changes["rows"] && this.rows && this.rows.length > 0) { this.columns = this._dataTableService.colsTable( this.colsname, diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html index ce616043d..4ca680acc 100644 --- a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html @@ -107,7 +107,7 @@ diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts index dc577ae1f..e09c227a3 100644 --- a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts @@ -20,7 +20,7 @@ export class MonitoringPropertiesGComponent implements OnInit { @Input() selectedObj: ISitesGroup; @Input() bEdit: boolean; @Output() bEditChange = new EventEmitter(); - + @Input() objectType:string; Object = Object; // @Input() currentUser; diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.html b/frontend/app/components/monitoring-sites/monitoring-sites.component.html index 2322122e5..6c3876e7e 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.html +++ b/frontend/app/components/monitoring-sites/monitoring-sites.component.html @@ -1,11 +1,16 @@ - + diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts index 486dd5932..948aa00b8 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts +++ b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts @@ -11,6 +11,7 @@ import { MonitoringGeomComponent } from "../../class/monitoring-geom-component"; import { setPopup } from "../../functions/popup"; import { GeoJSONService } from "../../services/geojson.service"; import { FormGroup, FormBuilder } from "@angular/forms"; +import { SitesService } from "../../services/sites.service"; const LIMIT = 10; @@ -31,10 +32,12 @@ export class MonitoringSitesComponent filters = {}; siteGroupLayer: L.FeatureGroup; @Input() bEdit:boolean; + @Input() objectType:string; objForm: FormGroup; constructor( private _sitesGroupService: SitesGroupService, + private _siteService: SitesService, private router: Router, private _Activatedroute: ActivatedRoute, private _geojsonService: GeoJSONService, @@ -46,6 +49,7 @@ export class MonitoringSitesComponent ngOnInit() { this.objForm = this._formBuilder.group({}); + this.objectType = this._siteService.addObjectType() this.initSite() } diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index 69abd880b..cc00fe5e4 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -1,3 +1,4 @@ +
diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 728f3255c..bcfc0bdea 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -11,6 +11,7 @@ import { ISite, ISitesGroup } from "../../interfaces/geom"; import { GeoJSONService } from "../../services/geojson.service"; import { MonitoringGeomComponent } from "../../class/monitoring-geom-component"; import { setPopup } from "../../functions/popup"; +import { DataTableService } from "../../services/data-table.service"; const LIMIT = 10; @@ -31,15 +32,20 @@ export class MonitoringSitesGroupsComponent @Input() columnNameSite: typeof columnNameSite = columnNameSite; @Input() sitesGroupsSelected: ISitesGroup; - @Input() rows; + // @Input() rows; @Input() colsname; @Input() obj; + @Input() objectType:string; + + constructor( private _sites_group_service: SitesGroupService, public geojsonService: GeoJSONService, private router: Router, + // IF prefered observable compare to ngOnChanges uncomment this: + // private _dataTableService:DataTableService, private _Activatedroute: ActivatedRoute, // private _routingService: RoutingService ) { super(); @@ -47,6 +53,7 @@ export class MonitoringSitesGroupsComponent } ngOnInit() { + this.objectType = this._sites_group_service.addObjectType() this.getSitesGroups(1); this.geojsonService.getSitesGroupsGeometries( this.onEachFeatureSiteGroups() @@ -82,6 +89,8 @@ export class MonitoringSitesGroupsComponent }; this.sitesGroups = data.items; this.colsname = this.columnNameSiteGroup; + // IF prefered observable compare to ngOnChanges uncomment this: + // this._dataTableService.changeColsTable(this.colsname,this.sitesGroups[0]) }); } diff --git a/frontend/app/services/data-table.service.ts b/frontend/app/services/data-table.service.ts index 6f350182b..579ead941 100644 --- a/frontend/app/services/data-table.service.ts +++ b/frontend/app/services/data-table.service.ts @@ -1,6 +1,6 @@ import { Injectable } from "@angular/core"; import { IColumn } from "../interfaces/column"; - +import { BehaviorSubject} from "rxjs"; interface ItemObjectTable { id: number | null; selected: boolean; @@ -17,9 +17,29 @@ export class DataTableService { rowStatus: ItemObjectTable; idObj: number; + + // IF prefered observable compare to ngOnChanges uncomment this: + // dataCol:IColumn[] =[{prop:"",name:"",description:""}] + // private dataCols = new BehaviorSubject(this.dataCol); + // currentCols = this.dataCols.asObservable(); + + constructor() {} - colsTable(colName, dataTable): IColumn[] { + // IF prefered observable compare to ngOnChanges uncomment this: + // changeColsTable(newCols:IColumn[],newRows){ + // const arr = Object.keys(newCols); + // const allColumn: IColumn[] = arr + // .filter((item) => Object.keys(newRows).includes(item)) + // .map((elm) => ({ + // name: newCols[elm], + // prop: elm, + // description: elm, + // })); + // this.dataCols.next(allColumn) + // } + + colsTable(colName:IColumn[], dataTable): IColumn[] { const arr = Object.keys(colName); const allColumn: IColumn[] = arr .filter((item) => Object.keys(dataTable).includes(item)) diff --git a/frontend/app/services/sites.service.ts b/frontend/app/services/sites.service.ts index 1aa757e10..df774348b 100644 --- a/frontend/app/services/sites.service.ts +++ b/frontend/app/services/sites.service.ts @@ -34,4 +34,12 @@ export class SitesService implements IGeomService { } ); } + + addObjectType():string { + return " un nouveau site" + } + + editObjectType():string { + return "Editer le site" + } } diff --git a/frontend/app/services/sites_group.service.ts b/frontend/app/services/sites_group.service.ts index 4b94c90df..9c581d01d 100644 --- a/frontend/app/services/sites_group.service.ts +++ b/frontend/app/services/sites_group.service.ts @@ -59,4 +59,12 @@ export class SitesGroupService implements IGeomService { patchGroupSite(id:number,updatedData:JsonData):Observable{ return this._cacheService.request("patch",`sites_groups/${id}`,{postData : updatedData}) } + + addObjectType():string { + return "un nouveau groupe de site" + } + + editObjectType():string { + return "Editer le groupe de site" + } } From de2118a2863f37e771f95aabe05629b00dc69e8c Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Wed, 1 Feb 2023 18:20:38 +0100 Subject: [PATCH 28/44] feat: improve rendering front "edit" and "add" Adding global object service to set object type and variable "add" or "edit" button Reviewed-by: andriacap [Refs_ticket]: #4 --- .../monitoring-datatable-g.component.ts | 8 +++---- .../monitoring-form.component-g.ts | 1 - .../monitoring-properties-g.component.ts | 4 +++- .../monitoring-sites.component.html | 1 - .../monitoring-sites.component.ts | 8 +++++-- .../monitoring-sitesgroups.component.html | 1 - .../monitoring-sitesgroups.component.ts | 8 +++++-- frontend/app/gnModule.module.ts | 4 +++- frontend/app/services/object.service.ts | 23 +++++++++++++++++++ frontend/app/services/sites.service.ts | 2 +- frontend/app/services/sites_group.service.ts | 2 +- 11 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 frontend/app/services/object.service.ts diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts index bc624f0d3..95b6d5ccd 100644 --- a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts @@ -14,6 +14,7 @@ import { debounceTime } from "rxjs/operators"; import { DataTableService } from "../../services/data-table.service"; import { IColumn } from "../../interfaces/column"; import { IPage } from "../../interfaces/page"; +import { ObjectService } from "../../services/object.service"; interface ItemObjectTable { id: number | null; @@ -34,8 +35,6 @@ export class MonitoringDatatableGComponent implements OnInit { @Input() page: IPage = { count: 0, limit: 0, page: 0 }; @Input() obj; - @Input() objectType:string; - @Input() rowStatus: Array; @Output() rowStatusChange = new EventEmitter(); @@ -52,6 +51,7 @@ export class MonitoringDatatableGComponent implements OnInit { displayFilter: boolean = false; objectsStatus: ItemsObjectTable; + objectType:string =''; columns; row_save; selected = []; @@ -61,7 +61,7 @@ export class MonitoringDatatableGComponent implements OnInit { @ViewChild("actionsTemplate") actionsTemplate: TemplateRef; @ViewChild("hdrTpl") hdrTpl: TemplateRef; - constructor(private _dataTableService: DataTableService) {} + constructor(private _dataTableService: DataTableService, private _objService: ObjectService) {} ngOnInit() { console.log("DataTableComponent colname", this.colsname); @@ -75,7 +75,7 @@ export class MonitoringDatatableGComponent implements OnInit { // IF prefered observable compare to ngOnChanges uncomment this: // this._dataTableService.currentCols.subscribe(newCols => { this.columns = newCols }) - + this._objService.currentObjectType.subscribe(newObjType => { this.objectType = newObjType }) this.filters = {}; this.filterSubject.pipe(debounceTime(500)).subscribe(() => { diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts index 55f2b7574..0f2cf03c2 100644 --- a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts +++ b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts @@ -66,7 +66,6 @@ export class MonitoringFormComponentG implements OnInit { // this.obj.moduleCode = "generic"; // this.obj.objectType = "sites_group"; console.log(this.obj); - this._editService.currentData.subscribe(dataToEdit => { this.obj = dataToEdit console.log("inside subscribe FORM",this.obj) diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts index e09c227a3..2581d0fd2 100644 --- a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts @@ -10,6 +10,7 @@ import { FormControl } from "@angular/forms"; import { extendedDetailsSiteGroup } from "../../class/monitoring-sites-group"; import { ISitesGroup } from "../../interfaces/geom"; import { EditObjectService } from "../../services/edit-object.service"; +import { ObjectService } from "../../services/object.service"; @Component({ selector: "pnx-monitoring-properties-g", @@ -33,11 +34,12 @@ export class MonitoringPropertiesGComponent implements OnInit { bUpdateSyntheseSpinner = false; public modalReference; - constructor(private _editService: EditObjectService) {} + constructor(private _editService: EditObjectService,private _objService: ObjectService) {} ngOnInit() { console.log("selectedObj", this.selectedObj); console.log("infosColsSiteGroups", this.infosColsSiteGroups); + this._objService.currentObjectTypeParent.subscribe(newObjType => { this.objectType = newObjType }) } onEditClick() { diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.html b/frontend/app/components/monitoring-sites/monitoring-sites.component.html index 6c3876e7e..4c9a60e1c 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.html +++ b/frontend/app/components/monitoring-sites/monitoring-sites.component.html @@ -22,5 +22,4 @@ [obj]="sites" (rowStatusChange)="onSelect($event)" (onDetailsRow)="seeDetails($event)" - [objectType]="objectType" > diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts index 948aa00b8..f6791a7a1 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts +++ b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts @@ -12,6 +12,7 @@ import { setPopup } from "../../functions/popup"; import { GeoJSONService } from "../../services/geojson.service"; import { FormGroup, FormBuilder } from "@angular/forms"; import { SitesService } from "../../services/sites.service"; +import { ObjectService } from "../../services/object.service"; const LIMIT = 10; @@ -32,12 +33,13 @@ export class MonitoringSitesComponent filters = {}; siteGroupLayer: L.FeatureGroup; @Input() bEdit:boolean; - @Input() objectType:string; objForm: FormGroup; + objectType:string; constructor( private _sitesGroupService: SitesGroupService, private _siteService: SitesService, + private _objService:ObjectService, private router: Router, private _Activatedroute: ActivatedRoute, private _geojsonService: GeoJSONService, @@ -49,7 +51,8 @@ export class MonitoringSitesComponent ngOnInit() { this.objForm = this._formBuilder.group({}); - this.objectType = this._siteService.addObjectType() + // this.objectType = this._siteService.addObjectType() + this._objService.changeObjectType(this._siteService.addObjectType()) this.initSite() } @@ -123,6 +126,7 @@ export class MonitoringSitesComponent seeDetails($event) { console.log("seeDetails", $event); + this._objService.changeObjectTypeParent(this._siteService.editObjectType()) // this.router.navigate([$event.id_sites_group], { // relativeTo: this._Activatedroute, // }); diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index cc00fe5e4..41cf18421 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -9,6 +9,5 @@ (onSetPage)="setPage($event)" [obj]="sitesGroups" (onDetailsRow)="seeDetails($event)" - [objectType]="objectType" > diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index bcfc0bdea..e890c3dc6 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -12,6 +12,7 @@ import { GeoJSONService } from "../../services/geojson.service"; import { MonitoringGeomComponent } from "../../class/monitoring-geom-component"; import { setPopup } from "../../functions/popup"; import { DataTableService } from "../../services/data-table.service"; +import { ObjectService } from "../../services/object.service"; const LIMIT = 10; @@ -35,7 +36,7 @@ export class MonitoringSitesGroupsComponent // @Input() rows; @Input() colsname; @Input() obj; - @Input() objectType:string; + objectType:string; @@ -44,6 +45,7 @@ export class MonitoringSitesGroupsComponent private _sites_group_service: SitesGroupService, public geojsonService: GeoJSONService, private router: Router, + private _objService:ObjectService, // IF prefered observable compare to ngOnChanges uncomment this: // private _dataTableService:DataTableService, private _Activatedroute: ActivatedRoute, // private _routingService: RoutingService @@ -53,7 +55,8 @@ export class MonitoringSitesGroupsComponent } ngOnInit() { - this.objectType = this._sites_group_service.addObjectType() + this._objService.changeObjectTypeParent(this._sites_group_service.editObjectType()) + this._objService.changeObjectType(this._sites_group_service.addObjectType()) this.getSitesGroups(1); this.geojsonService.getSitesGroupsGeometries( this.onEachFeatureSiteGroups() @@ -96,6 +99,7 @@ export class MonitoringSitesGroupsComponent seeDetails($event) { // TODO: routerLink + this._objService.changeObjectTypeParent(this._sites_group_service.editObjectType()) this.router.navigate([$event.id_sites_group], { relativeTo: this._Activatedroute, }); diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index 55de96b25..dc5157340 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -42,6 +42,7 @@ import { MonitoringSitesComponent } from "./components/monitoring-sites/monitori import { MonitoringMapListComponent } from "./components/monitoring-map-list/monitoring-map-list.component"; import { MonitoringFormComponentG } from "./components/monitoring-form-g/monitoring-form.component-g"; import { EditObjectService } from "./services/edit-object.service"; +import { ObjectService } from "./services/object.service"; // my module routing const routes: Routes = [ @@ -124,7 +125,8 @@ const routes: Routes = [ SitesGroupService, SitesService, GeoJSONService, - EditObjectService + EditObjectService, + ObjectService // RoutingService ], bootstrap: [ModulesComponent], diff --git a/frontend/app/services/object.service.ts b/frontend/app/services/object.service.ts new file mode 100644 index 000000000..c570f506c --- /dev/null +++ b/frontend/app/services/object.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from "@angular/core"; +import { BehaviorSubject } from "rxjs"; + +@Injectable() +export class ObjectService { + objectType: string = ""; + private dataObjType = new BehaviorSubject(this.objectType); + currentObjectType = this.dataObjType.asObservable(); + + objectTypeParent: string = ""; + private dataObjTypeParent = new BehaviorSubject(this.objectTypeParent); + currentObjectTypeParent = this.dataObjTypeParent.asObservable(); + + constructor() {} + + changeObjectType(newObjType: string) { + this.dataObjType.next(newObjType); + } + + changeObjectTypeParent(newObjType: string) { + this.dataObjTypeParent.next(newObjType); + } +} diff --git a/frontend/app/services/sites.service.ts b/frontend/app/services/sites.service.ts index df774348b..9f02f79be 100644 --- a/frontend/app/services/sites.service.ts +++ b/frontend/app/services/sites.service.ts @@ -40,6 +40,6 @@ export class SitesService implements IGeomService { } editObjectType():string { - return "Editer le site" + return "le site" } } diff --git a/frontend/app/services/sites_group.service.ts b/frontend/app/services/sites_group.service.ts index 9c581d01d..ae006380a 100644 --- a/frontend/app/services/sites_group.service.ts +++ b/frontend/app/services/sites_group.service.ts @@ -65,6 +65,6 @@ export class SitesGroupService implements IGeomService { } editObjectType():string { - return "Editer le groupe de site" + return "le groupe de site" } } From e72ee0acd2ad6127de5044db88e13a62420c4e7c Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Thu, 2 Feb 2023 16:40:48 +0100 Subject: [PATCH 29/44] feat: improving patch method object Adding service to share request patch,get in order to to re-use the service in form component according to the type pass inside the formcomponent Adding decorator errorhandler for blueprint routes Reviewed-by:andriacap [Refs_ticket]: #4 --- .../routes/sites_groups.py | 37 ++- .../utils/errors/errorHandler.py | 18 +- .../app/class/monitoring-form-component.ts | 15 + .../monitoring-form.component-g.ts | 258 +++++++++--------- .../monitoring-sites.component.ts | 4 +- .../monitoring-sitesgroups.component.ts | 3 +- frontend/app/gnModule.module.ts | 9 +- frontend/app/interfaces/form.ts | 7 + frontend/app/interfaces/geom.ts | 7 +- frontend/app/interfaces/response.ts | 11 +- frontend/app/services/api-geom.service.ts | 111 ++++++++ frontend/app/services/geojson.service.ts | 4 +- frontend/app/services/sites.service.ts | 46 +--- frontend/app/services/sites_group.service.ts | 73 +---- frontend/app/types/response.ts | 4 + 15 files changed, 341 insertions(+), 266 deletions(-) create mode 100644 frontend/app/class/monitoring-form-component.ts create mode 100644 frontend/app/interfaces/form.ts create mode 100644 frontend/app/services/api-geom.service.ts create mode 100644 frontend/app/types/response.ts diff --git a/backend/gn_module_monitoring/routes/sites_groups.py b/backend/gn_module_monitoring/routes/sites_groups.py index fa38b2359..c5c156ff8 100644 --- a/backend/gn_module_monitoring/routes/sites_groups.py +++ b/backend/gn_module_monitoring/routes/sites_groups.py @@ -1,9 +1,11 @@ -from flask import jsonify, request +from flask import jsonify, request,json from geonature.utils.env import db from gn_module_monitoring.utils.strings.strings import gettext from sqlalchemy import func from werkzeug.datastructures import MultiDict +from werkzeug.exceptions import HTTPException + from gn_module_monitoring.blueprint import blueprint from gn_module_monitoring.monitoring.models import TMonitoringSites, TMonitoringSitesGroups from gn_module_monitoring.monitoring.schemas import MonitoringSitesGroupsSchema @@ -82,15 +84,28 @@ def patch(_id): continue else: item = item_schema.load(item_json) - try: - item_schema.load(item_json) - db.session.add(item) - db.session.commit() - except ValidationError as err: - return InvalidUsage( - gettext("item_not_validated").format(err.messages), status_code=422, payload=item_json + item_schema.load(item_json) + db.session.add(item) + db.session.commit() + return item_schema.dump(item), 201 + + +@blueprint.errorhandler(ValidationError) +def handle_validation_error(error): + return InvalidUsage( + gettext("item_not_validated").format(error.messages), status_code=422, payload=error.data ).to_dict() - except: - return InvalidUsage("Internal Error", status_code=500).to_dict() - return item_schema.dump(item), 201 +# @blueprint.errorhandler(HTTPException) +# def handle_exception(e): +# """Return JSON instead of HTML for HTTP errors.""" +# # start with the correct headers and status code from the error +# response = e.get_response() +# # replace the body with JSON +# response.data = json.dumps({ +# "code": e.code, +# "name": e.name, +# "description": e.description, +# }) +# response.content_type = "application/json" +# return response \ No newline at end of file diff --git a/backend/gn_module_monitoring/utils/errors/errorHandler.py b/backend/gn_module_monitoring/utils/errors/errorHandler.py index 3fed70bf2..92401d02d 100644 --- a/backend/gn_module_monitoring/utils/errors/errorHandler.py +++ b/backend/gn_module_monitoring/utils/errors/errorHandler.py @@ -1,30 +1,20 @@ -# class APIError(Exception): -# """All custom API Exceptions""" -# pass +from geonature.utils.errors import GeonatureApiError -class InvalidUsage(Exception): +class InvalidUsage(GeonatureApiError): status_code = 400 def __init__(self, message, status_code=None, payload=None): - Exception.__init__(self) + GeonatureApiError.__init__(self, message, status_code) self.message = message if status_code is not None: self.status_code = status_code self.payload = payload - def to_dict(self): rv = {} # rv['payload'] = dict(self.payload or ()) rv["payload"] = self.payload rv["message"] = self.message rv["status_code"] = self.status_code - return (rv,self.status_code) - - -class APIAuthError(Exception): - """Custom Authentication Error Class.""" - - code = 403 - description = "Authentication Error" + return (rv, self.status_code) diff --git a/frontend/app/class/monitoring-form-component.ts b/frontend/app/class/monitoring-form-component.ts new file mode 100644 index 000000000..535c99806 --- /dev/null +++ b/frontend/app/class/monitoring-form-component.ts @@ -0,0 +1,15 @@ +import { ISite, ISitesGroup } from "../interfaces/geom"; +import { Observable } from "rxjs"; +import { JsonData } from "../types/jsondata"; +import { Resp } from "../types/response"; + +type patchPostFunction = ( + id: number, + data: JsonData | ISitesGroup | ISite +) => Observable; +export class MonitoringFormComponent { + protected patchItemCallback: patchPostFunction; + protected postItemCallback: patchPostFunction; + + constructor() {} +} diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts index 0f2cf03c2..c5076762b 100644 --- a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts +++ b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts @@ -1,16 +1,21 @@ -import { Component, OnInit, Input, Output, EventEmitter,SimpleChanges, } from "@angular/core"; -import { FormGroup, FormBuilder, Validators } from "@angular/forms"; +import { + Component, + OnInit, + Input, + Output, + EventEmitter, + SimpleChanges, +} from "@angular/core"; +import { FormGroup, FormBuilder } from "@angular/forms"; import { MonitoringObject } from "../../class/monitoring-object"; -// import { Router } from "@angular/router"; import { ConfigService } from "../../services/config.service"; -import { DataUtilsService } from "../../services/data-utils.service"; import { CommonService } from "@geonature_common/service/common.service"; import { DynamicFormService } from "@geonature_common/form/dynamic-form-generator/dynamic-form.service"; import { ActivatedRoute } from "@angular/router"; import { EditObjectService } from "../../services/edit-object.service"; -import { SitesGroupService } from "../../services/sites_group.service"; import { Router } from "@angular/router"; -import { JsonData } from "../../types/jsondata"; +import { IDataForm } from "../../interfaces/form"; +import { ApiGeomService } from "../../services/api-geom.service"; @Component({ selector: "pnx-monitoring-form-g", templateUrl: "./monitoring-form.component-g.html", @@ -31,10 +36,10 @@ export class MonitoringFormComponentG implements OnInit { @Output() bEditChange = new EventEmitter(); @Input() sites: {}; - dataForm:JsonData; + dataForm: IDataForm; searchSite = ""; - obj:any; + obj: any; objFormsDefinition; meta: {}; @@ -54,10 +59,9 @@ export class MonitoringFormComponentG implements OnInit { private _route: ActivatedRoute, private _configService: ConfigService, private _commonService: CommonService, - private _dataUtilsService: DataUtilsService, private _dynformService: DynamicFormService, private _editService: EditObjectService, - private _siteGpService: SitesGroupService, + private _apiGeomService: ApiGeomService, private _router: Router ) {} @@ -66,101 +70,100 @@ export class MonitoringFormComponentG implements OnInit { // this.obj.moduleCode = "generic"; // this.obj.objectType = "sites_group"; console.log(this.obj); - this._editService.currentData.subscribe(dataToEdit => { - this.obj = dataToEdit - console.log("inside subscribe FORM",this.obj) - // this.obj.moduleCode = "generic"; - // this.obj.objectType = "sites_group"; - this.obj.bIsInitialized = true - this._configService - .init(this.obj.moduleCode) - .pipe() - .subscribe(() => { - // return this._route.queryParamMap; - // }) - // .subscribe((queryParams) => { - this.queryParams = this._route.snapshot.queryParams || {}; - this.bChainInput = this._configService.frontendParams()["bChainInput"]; - - const schema = this._configService.schema( - this.obj.moduleCode, - this.obj.objectType - ); - console.log(schema); - this.obj[this.obj.moduleCode] = schema - // const schema = this.obj.schema(); - - // init objFormsDefinition - - // meta pour les parametres dynamiques - // ici pour avoir acces aux nomenclatures - this.meta = { - // nomenclatures: this._dataUtilsService.getDataUtil('nomenclature'), - // dataset: this._dataUtilsService.getDataUtil('dataset'), - // id_role: this.currentUser.id_role, - bChainInput: this.bChainInput, - parents: this.obj.parents, - }; - - console.log(this.meta); - this.objFormsDefinition = this._dynformService - .formDefinitionsdictToArray(schema, this.meta) - .filter((formDef) => formDef.type_widget) - .sort((a, b) => { - // medias à la fin - return a.attribut_name === "medias" - ? +1 - : b.attribut_name === "medias" - ? -1 - : 0; - }); - - // display_form pour customiser l'ordre dans le formulaire - // les éléments de display form sont placé en haut dans l'ordre du tableau - // tous les éléments non cachés restent affichés - - let displayProperties = [ - ...(this._configService.configModuleObjectParam( + this._editService.currentData.subscribe((dataToEdit) => { + this.obj = dataToEdit; + console.log("inside subscribe FORM", this.obj); + // this.obj.moduleCode = "generic"; + // this.obj.objectType = "sites_group"; + this.obj.bIsInitialized = true; + this._configService + .init(this.obj.moduleCode) + .pipe() + .subscribe(() => { + // return this._route.queryParamMap; + // }) + // .subscribe((queryParams) => { + this.queryParams = this._route.snapshot.queryParams || {}; + this.bChainInput = + this._configService.frontendParams()["bChainInput"]; + + const schema = this._configService.schema( this.obj.moduleCode, - this.obj.objectType, - "display_properties" - ) || []), - ]; - if (displayProperties && displayProperties.length) { - displayProperties.reverse(); - this.objFormsDefinition.sort((a, b) => { - let indexA = displayProperties.findIndex( - (e) => e == a.attribut_name - ); - let indexB = displayProperties.findIndex( - (e) => e == b.attribut_name - ); - return indexB - indexA; - }); - } - - // champs patch pour simuler un changement de valeur et déclencher le recalcul des propriété - // par exemple quand bChainInput change - this.objForm.addControl("patch_update", this._formBuilder.control(0)); - - // this._configService.configModuleObject(this.obj.moduleCode, this.obj.objectType); - // set geometry - // if (this.obj.config["geometry_type"]) { - // this.objForm.addControl( - // "geometry", - // this._formBuilder.control("", Validators.required) - // ); - // } - - // pour donner la valeur de idParent - - this.initForm(); - }); - }) - + this.obj.objectType + ); + console.log(schema); + this.obj[this.obj.moduleCode] = schema; + // const schema = this.obj.schema(); + + // init objFormsDefinition + + // meta pour les parametres dynamiques + // ici pour avoir acces aux nomenclatures + this.meta = { + // nomenclatures: this._dataUtilsService.getDataUtil('nomenclature'), + // dataset: this._dataUtilsService.getDataUtil('dataset'), + // id_role: this.currentUser.id_role, + bChainInput: this.bChainInput, + parents: this.obj.parents, + }; + + console.log(this.meta); + this.objFormsDefinition = this._dynformService + .formDefinitionsdictToArray(schema, this.meta) + .filter((formDef) => formDef.type_widget) + .sort((a, b) => { + // medias à la fin + return a.attribut_name === "medias" + ? +1 + : b.attribut_name === "medias" + ? -1 + : 0; + }); + + // display_form pour customiser l'ordre dans le formulaire + // les éléments de display form sont placé en haut dans l'ordre du tableau + // tous les éléments non cachés restent affichés + + let displayProperties = [ + ...(this._configService.configModuleObjectParam( + this.obj.moduleCode, + this.obj.objectType, + "display_properties" + ) || []), + ]; + if (displayProperties && displayProperties.length) { + displayProperties.reverse(); + this.objFormsDefinition.sort((a, b) => { + let indexA = displayProperties.findIndex( + (e) => e == a.attribut_name + ); + let indexB = displayProperties.findIndex( + (e) => e == b.attribut_name + ); + return indexB - indexA; + }); + } + + // champs patch pour simuler un changement de valeur et déclencher le recalcul des propriété + // par exemple quand bChainInput change + this.objForm.addControl("patch_update", this._formBuilder.control(0)); + + // this._configService.configModuleObject(this.obj.moduleCode, this.obj.objectType); + // set geometry + // if (this.obj.config["geometry_type"]) { + // this.objForm.addControl( + // "geometry", + // this._formBuilder.control("", Validators.required) + // ); + // } + + // pour donner la valeur de idParent + + this.initForm(); + }); + }); } - /** pour réutiliser des paramètres déjà saisis */ keepDefinitions() { return this.objFormsDefinition.filter((def) => @@ -187,13 +190,13 @@ export class MonitoringFormComponentG implements OnInit { } this.setQueryParams(); - console.log("Init Form" , this.obj) + console.log("Init Form", this.obj); // pour donner la valeur de l'objet au formulaire this._editService.formValues(this.obj).subscribe((formValue) => { - console.log(formValue) + console.log(formValue); this.objForm.patchValue(formValue); this.setDefaultFormValue(); - this.dataForm = formValue + this.dataForm = formValue; // reset geom ? }); } @@ -277,14 +280,10 @@ export class MonitoringFormComponentG implements OnInit { /** * Valider et aller à la page de l'objet */ - navigateToDetail(id,objectType,queryParams) { - // patch bug navigation + navigateToDetail(id, objectType, queryParams) { + // patch bug navigation this._router.navigate( - [ - "monitorings", - objectType, - id, - ].filter((s) => !!s), + ["monitorings", objectType, id].filter((s) => !!s), { queryParams, } @@ -307,12 +306,12 @@ export class MonitoringFormComponentG implements OnInit { /** TODO améliorer site etc.. */ onSubmit() { - console.log(this.obj) - const {patch_update, ...sendValue} = this.dataForm + console.log(this.obj); + const { patch_update, ...sendValue } = this.dataForm; const action = this.obj.id - // ? this.obj.patch(this.objForm.value) - // : this.obj.post(this.objForm.value); - ? this._siteGpService.patchGroupSite(this.obj.id,sendValue) + ? // ? this.obj.patch(this.objForm.value) + // : this.obj.post(this.objForm.value); + this._apiGeomService.patch(this.obj.id, sendValue) : this.obj.post(this.objForm.value); const actionLabel = this.obj.id ? "Modification" : "Création"; action.subscribe((objData) => { @@ -333,10 +332,20 @@ export class MonitoringFormComponentG implements OnInit { } else if (this.bAddChildren) { this.navigateToAddChildren(); } else { - if (this._configService.configModuleObjectParam(this.obj.moduleCode,this.obj.objectType,"redirect_to_parent")) { + if ( + this._configService.configModuleObjectParam( + this.obj.moduleCode, + this.obj.objectType, + "redirect_to_parent" + ) + ) { this.navigateToParent(); } else { - this.navigateToDetail(this.obj.id,this.obj.objectType,this.queryParams); + this.navigateToDetail( + this.obj.id, + this.obj.objectType, + this.queryParams + ); } } }); @@ -368,9 +377,12 @@ export class MonitoringFormComponentG implements OnInit { onObjFormValueChange(event) { // let {id_module,medias, ...rest} = this.objForm.value; // this.dataForm = rest - this.dataForm = this.objForm.value - console.log(this.dataForm) - const change = this._configService.change(this.obj.moduleCode ,this.obj.objectType ); + this.dataForm = this.objForm.value; + console.log(this.dataForm); + const change = this._configService.change( + this.obj.moduleCode, + this.obj.objectType + ); if (!change) { return; } @@ -399,7 +411,7 @@ export class MonitoringFormComponentG implements OnInit { console.log("inside ngOnChanges"); console.log("changes", changes); if (changes["obj"] && this.obj) { - console.log(this.obj) + console.log(this.obj); } } } diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts index f6791a7a1..23778dca7 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts +++ b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts @@ -5,13 +5,13 @@ import { tap, map, mergeMap } from "rxjs/operators"; import * as L from "leaflet"; import { ISite, ISitesGroup } from "../../interfaces/geom"; import { IPage, IPaginated } from "../../interfaces/page"; -import { SitesGroupService } from "../../services/sites_group.service"; +// import { } from "../../services/sites_group.service"; import { columnNameSite } from "../../class/monitoring-site"; import { MonitoringGeomComponent } from "../../class/monitoring-geom-component"; import { setPopup } from "../../functions/popup"; import { GeoJSONService } from "../../services/geojson.service"; import { FormGroup, FormBuilder } from "@angular/forms"; -import { SitesService } from "../../services/sites.service"; +import { SitesService ,SitesGroupService} from "../../services/api-geom.service"; import { ObjectService } from "../../services/object.service"; const LIMIT = 10; diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index e890c3dc6..d715eb966 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit, Input } from "@angular/core"; -import { SitesGroupService } from "../../services/sites_group.service"; +import { SitesGroupService } from "../../services/api-geom.service"; import { columnNameSiteGroup } from "../../class/monitoring-sites-group"; import { IPaginated, IPage } from "../../interfaces/page"; import { @@ -11,7 +11,6 @@ import { ISite, ISitesGroup } from "../../interfaces/geom"; import { GeoJSONService } from "../../services/geojson.service"; import { MonitoringGeomComponent } from "../../class/monitoring-geom-component"; import { setPopup } from "../../functions/popup"; -import { DataTableService } from "../../services/data-table.service"; import { ObjectService } from "../../services/object.service"; const LIMIT = 10; diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index dc5157340..47e509e40 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -34,15 +34,16 @@ import { MatSelectModule } from "@angular/material/select"; import { MatInputModule } from "@angular/material/input"; import { MonitoringSitesGroupsComponent } from "./components/monitoring-sitesgroups/monitoring-sitesgroups.component"; import { DataTableService } from "./services/data-table.service"; -import { SitesGroupService } from "./services/sites_group.service"; +// import { } from "./services/sites_group.service"; import { MonitoringPropertiesGComponent } from "./components/monitoring-properties-g/monitoring-properties-g.component"; -import { SitesService } from "./services/sites.service"; +// import { } from "./services/sites.service"; import { GeoJSONService } from "./services/geojson.service"; import { MonitoringSitesComponent } from "./components/monitoring-sites/monitoring-sites.component"; import { MonitoringMapListComponent } from "./components/monitoring-map-list/monitoring-map-list.component"; import { MonitoringFormComponentG } from "./components/monitoring-form-g/monitoring-form.component-g"; import { EditObjectService } from "./services/edit-object.service"; import { ObjectService } from "./services/object.service"; +import { SitesGroupService,SitesService,ApiGeomService } from "./services/api-geom.service"; // my module routing const routes: Routes = [ @@ -126,8 +127,8 @@ const routes: Routes = [ SitesService, GeoJSONService, EditObjectService, - ObjectService - // RoutingService + ObjectService, + ApiGeomService ], bootstrap: [ModulesComponent], schemas: [ diff --git a/frontend/app/interfaces/form.ts b/frontend/app/interfaces/form.ts new file mode 100644 index 000000000..e57edf803 --- /dev/null +++ b/frontend/app/interfaces/form.ts @@ -0,0 +1,7 @@ +import { JsonData } from "../types/jsondata"; +import { ISite, ISitesGroup } from "./geom"; + +export interface IDataForm extends JsonData, ISitesGroup, ISite { + patch_update:number + } + \ No newline at end of file diff --git a/frontend/app/interfaces/geom.ts b/frontend/app/interfaces/geom.ts index b3382c197..8a03db23d 100644 --- a/frontend/app/interfaces/geom.ts +++ b/frontend/app/interfaces/geom.ts @@ -1,6 +1,7 @@ import { GeoJSON } from "geojson"; import { Observable } from "rxjs"; import { JsonData } from "../types/jsondata"; +import { Resp } from "../types/response"; import { IPaginated } from "./page"; export interface IGeomObject { @@ -9,7 +10,7 @@ export interface IGeomObject { } export interface ISitesGroup extends IGeomObject { - pk:number; + pk: number; comments?: string; id_sites_group: number; nb_sites: number; @@ -42,8 +43,8 @@ export interface IGeomService { page: number, params: JsonData ): Observable>; - get_geometries(): Observable; + get_geometries(params: JsonData): Observable; // create(obj: IGeomObject) - // patch(obj: IGeomObject) + patch(id: number, updatedData: IGeomObject): Observable; // delete(obj: IGeomObject) } diff --git a/frontend/app/interfaces/response.ts b/frontend/app/interfaces/response.ts index 4cb97ddef..317f5c94d 100644 --- a/frontend/app/interfaces/response.ts +++ b/frontend/app/interfaces/response.ts @@ -1,7 +1,6 @@ -import { JsonData } from "../types/jsondata" - +import { JsonData } from "../types/jsondata"; export interface ResponseUpdated { - message:string - payload:JsonData - status_code:number -} \ No newline at end of file + message: string; + payload: JsonData; + status_code: number; +} diff --git a/frontend/app/services/api-geom.service.ts b/frontend/app/services/api-geom.service.ts new file mode 100644 index 000000000..86f0bd0e0 --- /dev/null +++ b/frontend/app/services/api-geom.service.ts @@ -0,0 +1,111 @@ +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; +import { GeoJSON } from "geojson"; + +import { CacheService } from "./cache.service"; +import { IGeomService, ISitesGroup, ISite } from "../interfaces/geom"; +import { IPaginated } from "../interfaces/page"; +import { JsonData } from "../types/jsondata"; +import { Resp } from "../types/response"; + +export enum endPoints { + sites_groups = "sites_groups", + sites = "sites", +} + +@Injectable() +export class ApiGeomService implements IGeomService { + public objectType: endPoints = endPoints.sites_groups; + + constructor(protected _cacheService: CacheService) { + this.init(); + } + + init() { + this.objectType = endPoints.sites_groups; + console.log(this.objectType); + } + get( + page: number = 1, + limit: number = 10, + params: JsonData = {} + ): Observable> { + return this._cacheService.request< + Observable> + >("get", this.objectType, { + queryParams: { page, limit, ...params }, + }); + } + + getById(id: number): Observable { + return this._cacheService.request>( + "get", + `${this.objectType}/${id}` + ); + } + + get_geometries(params: JsonData = {}): Observable { + return this._cacheService.request>( + "get", + `${this.objectType}/geometries`, + { + queryParams: { ...params }, + } + ); + } + + patch(id: number, updatedData: ISitesGroup | ISite): Observable { + return this._cacheService.request("patch", `${this.objectType}/${id}`, { + postData: updatedData, + }); + } +} + +@Injectable() +export class SitesGroupService extends ApiGeomService { + constructor(_cacheService: CacheService) { + super(_cacheService); + } + init(): void { + this.objectType = endPoints.sites_groups; + } + + getSitesChild( + page: number = 1, + limit: number = 10, + params: JsonData = {} + ): Observable> { + return this._cacheService.request>>( + "get", + `sites`, + { + queryParams: { page, limit, ...params }, + } + ); + } + + addObjectType(): string { + return "un nouveau groupe de site"; + } + + editObjectType(): string { + return "le groupe de site"; + } +} + +@Injectable() +export class SitesService extends ApiGeomService { + constructor(_cacheService: CacheService) { + super(_cacheService); + } + init(): void { + this.objectType = endPoints.sites; + } + addObjectType(): string { + return " un nouveau site"; + } + + editObjectType(): string { + return "le site"; + } +} diff --git a/frontend/app/services/geojson.service.ts b/frontend/app/services/geojson.service.ts index 72f3cfe10..22a26e980 100644 --- a/frontend/app/services/geojson.service.ts +++ b/frontend/app/services/geojson.service.ts @@ -5,8 +5,8 @@ import { map } from "rxjs/operators"; import { GeoJSON } from "geojson"; import { MapService } from "@geonature_common/map/map.service"; -import { SitesGroupService } from "./sites_group.service"; -import { SitesService } from "./sites.service"; +import { SitesService,SitesGroupService } from "./api-geom.service"; + // This service will be used for sites and sites groups diff --git a/frontend/app/services/sites.service.ts b/frontend/app/services/sites.service.ts index 9f02f79be..c4a72d66d 100644 --- a/frontend/app/services/sites.service.ts +++ b/frontend/app/services/sites.service.ts @@ -1,45 +1,17 @@ import { Injectable } from "@angular/core"; -import { Observable } from "rxjs"; -import { GeoJSON } from "geojson"; - -import { CacheService } from "./cache.service"; -import { IGeomService, ISite } from "../interfaces/geom"; -import { IPaginated } from "../interfaces/page"; -import { JsonData } from "../types/jsondata"; +import { ApiGeomService, endPoints } from "./api-geom.service"; @Injectable() -export class SitesService implements IGeomService { - constructor(private _cacheService: CacheService) {} - - get( - page: number = 1, - limit: number = 10, - params: JsonData = {} - ): Observable> { - return this._cacheService.request>>( - "get", - `sites`, - { - queryParams: { page, limit, ...params }, - } - ); +export class SitesService extends ApiGeomService { + constructor(_cacheService, objectType: endPoints) { + super(_cacheService); + this.objectType = endPoints.sites; } - - get_geometries(params: JsonData = {}): Observable { - return this._cacheService.request>( - "get", - "sites/geometries", - { - queryParams: { ...params }, - } - ); - } - - addObjectType():string { - return " un nouveau site" + addObjectType(): string { + return " un nouveau site"; } - editObjectType():string { - return "le site" + editObjectType(): string { + return "le site"; } } diff --git a/frontend/app/services/sites_group.service.ts b/frontend/app/services/sites_group.service.ts index ae006380a..55f5a5b4b 100644 --- a/frontend/app/services/sites_group.service.ts +++ b/frontend/app/services/sites_group.service.ts @@ -1,70 +1,19 @@ import { Injectable } from "@angular/core"; -import { Observable } from "rxjs"; -import { GeoJSON } from "geojson"; - -import { CacheService } from "./cache.service"; -import { IGeomService, ISitesGroup, ISite } from "../interfaces/geom"; -import { IPaginated } from "../interfaces/page"; -import { JsonData } from "../types/jsondata"; -import { ResponseUpdated } from "../interfaces/response"; +import { ApiGeomService } from "./api-geom.service"; +import { endPoints } from "./api-geom.service"; @Injectable() -export class SitesGroupService implements IGeomService { - constructor(private _cacheService: CacheService) {} - - get( - page: number = 1, - limit: number = 10, - params: JsonData = {} - ): Observable> { - return this._cacheService.request>>( - "get", - `sites_groups`, - { - queryParams: { page, limit, ...params }, - } - ); - } - - getById(id: number): Observable { - return this._cacheService.request>( - "get", - `sites_groups/${id}` - ); - } - - get_geometries(params: JsonData = {}): Observable { - return this._cacheService.request>( - "get", - "sites_groups/geometries", - { - queryParams: { ...params }, - } - ); - } - - getSitesChild( - page: number = 1, - limit: number = 10, - params: JsonData = {} - ): Observable> { - return this._cacheService.request>>( - "get", - `sites`, - { - queryParams: { page, limit, ...params }, - } - ); - } - - patchGroupSite(id:number,updatedData:JsonData):Observable{ - return this._cacheService.request("patch",`sites_groups/${id}`,{postData : updatedData}) +export class SitesGroupService extends ApiGeomService { + constructor(_cacheService) { + super(_cacheService); + this.objectType = endPoints.sites_groups; + console.log(this.objectType); } - addObjectType():string { - return "un nouveau groupe de site" + addObjectType(): string { + return "un nouveau groupe de site"; } - editObjectType():string { - return "le groupe de site" + editObjectType(): string { + return "le groupe de site"; } } diff --git a/frontend/app/types/response.ts b/frontend/app/types/response.ts new file mode 100644 index 000000000..dd26b3360 --- /dev/null +++ b/frontend/app/types/response.ts @@ -0,0 +1,4 @@ +import { ISite, ISitesGroup } from "../interfaces/geom"; +import { ResponseUpdated } from "../interfaces/response"; + +export type Resp = ResponseUpdated | ISite | ISitesGroup; From 2b3632a0feb1cb08fe625e2aa31f597d989d2a30 Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Mon, 20 Feb 2023 10:09:19 +0100 Subject: [PATCH 30/44] feat: create site group method with form Route create with form component Using location pacakage to choose between edit form or init sitegroup (see to improve that) Rewiewed-by: andriacap [Refs ticket]: #4 --- .../monitoring/schemas.py | 1 + .../routes/sites_groups.py | 10 +++++ config/monitoring/generic/sites_group.json | 10 ----- .../monitoring-datatable-g.component.ts | 25 ++++++++--- .../monitoring-form.component-g.ts | 7 ++- .../monitoring-form.component.ts | 2 +- .../monitoring-sitesgroups.component.html | 9 ++++ .../monitoring-sitesgroups.component.ts | 45 +++++++++++++++++-- frontend/app/gnModule.module.ts | 2 + frontend/app/interfaces/geom.ts | 2 +- frontend/app/services/api-geom.service.ts | 6 +++ 11 files changed, 97 insertions(+), 22 deletions(-) diff --git a/backend/gn_module_monitoring/monitoring/schemas.py b/backend/gn_module_monitoring/monitoring/schemas.py index 2bd8d6038..66fe98ec9 100644 --- a/backend/gn_module_monitoring/monitoring/schemas.py +++ b/backend/gn_module_monitoring/monitoring/schemas.py @@ -32,6 +32,7 @@ class MonitoringSitesGroupsSchema(MA.SQLAlchemyAutoSchema): class Meta: model = TMonitoringSitesGroups exclude = ("geom_geojson",) + load_instance = True medias = MA.Nested(MediaSchema) pk = fields.Method("set_pk",dump_only=True) diff --git a/backend/gn_module_monitoring/routes/sites_groups.py b/backend/gn_module_monitoring/routes/sites_groups.py index c5c156ff8..f7455d09f 100644 --- a/backend/gn_module_monitoring/routes/sites_groups.py +++ b/backend/gn_module_monitoring/routes/sites_groups.py @@ -90,6 +90,16 @@ def patch(_id): return item_schema.dump(item), 201 +@blueprint.route("/sites_groups", methods=["POST"]) +def post(): + item_schema = MonitoringSitesGroupsSchema() + item_json = request.get_json() + item = item_schema.load(item_json) + db.session.add(item) + db.session.commit() + return item_schema.dump(item), 201 + + @blueprint.errorhandler(ValidationError) def handle_validation_error(error): return InvalidUsage( diff --git a/config/monitoring/generic/sites_group.json b/config/monitoring/generic/sites_group.json index d56dbff39..8512fdb0d 100644 --- a/config/monitoring/generic/sites_group.json +++ b/config/monitoring/generic/sites_group.json @@ -18,11 +18,6 @@ {"prop": "sites_group_code"} ], "generic": { - "id_sites_group": { - "type_widget": "text", - "attribut_label": "Id site", - "hidden": true - }, "sites_group_name": { "type_widget": "text", "attribut_label": "Nom", @@ -49,11 +44,6 @@ }, "nb_visits": { "attribut_label": "Nombre de visites" - }, - "medias": { - "type_widget": "medias", - "attribut_label": "Médias", - "schema_dot_table": "gn_monitoring.t_sites_groups" } } } diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts index 95b6d5ccd..f42646b42 100644 --- a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts @@ -9,6 +9,7 @@ import { SimpleChanges, TemplateRef, } from "@angular/core"; +import { Router, ActivatedRoute } from "@angular/router"; import { Subject } from "rxjs"; import { debounceTime } from "rxjs/operators"; import { DataTableService } from "../../services/data-table.service"; @@ -46,12 +47,13 @@ export class MonitoringDatatableGComponent implements OnInit { @Output() onFilter = new EventEmitter(); @Output() onSetPage = new EventEmitter(); @Output() onDetailsRow = new EventEmitter(); + @Output() addEvent = new EventEmitter(); private filterSubject: Subject = new Subject(); displayFilter: boolean = false; objectsStatus: ItemsObjectTable; - objectType:string =''; + objectType: string = ""; columns; row_save; selected = []; @@ -61,7 +63,12 @@ export class MonitoringDatatableGComponent implements OnInit { @ViewChild("actionsTemplate") actionsTemplate: TemplateRef; @ViewChild("hdrTpl") hdrTpl: TemplateRef; - constructor(private _dataTableService: DataTableService, private _objService: ObjectService) {} + constructor( + private _dataTableService: DataTableService, + private _objService: ObjectService, + private router: Router, + private _Activatedroute: ActivatedRoute + ) {} ngOnInit() { console.log("DataTableComponent colname", this.colsname); @@ -72,11 +79,13 @@ export class MonitoringDatatableGComponent implements OnInit { initDatatable() { console.log("Inside initDatatable"); console.log("this.rows", this.rows); - + // IF prefered observable compare to ngOnChanges uncomment this: // this._dataTableService.currentCols.subscribe(newCols => { this.columns = newCols }) - this._objService.currentObjectType.subscribe(newObjType => { this.objectType = newObjType }) - + this._objService.currentObjectType.subscribe((newObjType) => { + this.objectType = newObjType; + }); + this.filters = {}; this.filterSubject.pipe(debounceTime(500)).subscribe(() => { this.filter(); @@ -208,10 +217,14 @@ export class MonitoringDatatableGComponent implements OnInit { } navigateToAddChildren(_, rowId) { console.log("Inside navigateToAddChildren:", rowId); + this.addEvent.emit(rowId); + this.router.navigate(["create"], { + relativeTo: this._Activatedroute, + }); } navigateToDetail(row) { console.log("Inside navigateToDetail:", row); - row["id"] = row.pk + row["id"] = row.pk; this.onDetailsRow.emit(row); } } diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts index c5076762b..d083764e3 100644 --- a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts +++ b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts @@ -296,6 +296,8 @@ export class MonitoringFormComponentG implements OnInit { */ navigateToParent() { this.bEditChange.emit(false); // patch bug navigation + this._router.navigateByUrl('/monitorings/sites_group') + // this.obj.navigateToParent(); } @@ -312,7 +314,7 @@ export class MonitoringFormComponentG implements OnInit { ? // ? this.obj.patch(this.objForm.value) // : this.obj.post(this.objForm.value); this._apiGeomService.patch(this.obj.id, sendValue) - : this.obj.post(this.objForm.value); + : this._apiGeomService.create(sendValue) const actionLabel = this.obj.id ? "Modification" : "Création"; action.subscribe((objData) => { this._commonService.regularToaster( @@ -328,10 +330,13 @@ export class MonitoringFormComponentG implements OnInit { } if (this.bChainInput) { + console.log('bChainInput') this.resetObjForm(); } else if (this.bAddChildren) { + console.log('bAddChildren') this.navigateToAddChildren(); } else { + console.log('this._configService.configModuleObjectParam') if ( this._configService.configModuleObjectParam( this.obj.moduleCode, diff --git a/frontend/app/components/monitoring-form/monitoring-form.component.ts b/frontend/app/components/monitoring-form/monitoring-form.component.ts index 2e5102e62..22eb3625a 100644 --- a/frontend/app/components/monitoring-form/monitoring-form.component.ts +++ b/frontend/app/components/monitoring-form/monitoring-form.component.ts @@ -55,7 +55,7 @@ export class MonitoringFormComponent implements OnInit { ) {} ngOnInit() { - // console.log(this.obj) + console.log(this.obj) // this.obj.moduleCode = "generic" // this.obj.objectType = "sites_group" this._configService diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index 41cf18421..778abf048 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -1,6 +1,14 @@
+
diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index d715eb966..781199ac6 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit, Input } from "@angular/core"; +import { Location } from '@angular/common'; import { SitesGroupService } from "../../services/api-geom.service"; import { columnNameSiteGroup } from "../../class/monitoring-sites-group"; import { IPaginated, IPage } from "../../interfaces/page"; @@ -12,6 +13,8 @@ import { GeoJSONService } from "../../services/geojson.service"; import { MonitoringGeomComponent } from "../../class/monitoring-geom-component"; import { setPopup } from "../../functions/popup"; import { ObjectService } from "../../services/object.service"; +import { EditObjectService } from "../../services/edit-object.service"; +import { FormGroup, FormBuilder } from "@angular/forms"; const LIMIT = 10; @@ -36,9 +39,16 @@ export class MonitoringSitesGroupsComponent @Input() colsname; @Input() obj; objectType:string; - - - + @Input() isAddingForm:boolean; + objForm: FormGroup; + objInitForm:Object= {}; + // siteGroupEmpty={ + // "comments" :'', + // sites_group_code: string; + // sites_group_description: string; + // sites_group_name: string; + // uuid_sites_group: string; //FIXME: see if OK + // } constructor( private _sites_group_service: SitesGroupService, @@ -47,6 +57,9 @@ export class MonitoringSitesGroupsComponent private _objService:ObjectService, // IF prefered observable compare to ngOnChanges uncomment this: // private _dataTableService:DataTableService, + private _editService: EditObjectService, + private location: Location, + private _formBuilder: FormBuilder, private _Activatedroute: ActivatedRoute, // private _routingService: RoutingService ) { super(); @@ -54,6 +67,25 @@ export class MonitoringSitesGroupsComponent } ngOnInit() { + console.log(this.router.url) + console.log(this.location) + if (this.router.url == '/monitorings/sites_group'){ + this.isAddingForm = false + this.initSiteGroup() + } else { + console.log(this.objInitForm) + this._editService.changeDataSub(this.objInitForm); + this.isAddingForm = true + this.addComponent() + } + + } + + addComponent(){ + this.objForm = this._formBuilder.group({}); + } + + initSiteGroup(){ this._objService.changeObjectTypeParent(this._sites_group_service.editObjectType()) this._objService.changeObjectType(this._sites_group_service.addObjectType()) this.getSitesGroups(1); @@ -111,7 +143,14 @@ export class MonitoringSitesGroupsComponent // } } + addSiteGp($event){ + this.isAddingForm = true + console.log("ADD Site Groupe", $event) + } onSelect($event) { this.geojsonService.selectSitesGroupLayer($event); } + onObjChanged($event) { + console.log($event) + } } diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index 47e509e40..78f21ec81 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -73,6 +73,8 @@ const routes: Routes = [ path: "", component: MonitoringSitesGroupsComponent, }, + {path:"create", + component:MonitoringSitesGroupsComponent}, { path: ":id", component: MonitoringSitesComponent, diff --git a/frontend/app/interfaces/geom.ts b/frontend/app/interfaces/geom.ts index 8a03db23d..9d43b5cdf 100644 --- a/frontend/app/interfaces/geom.ts +++ b/frontend/app/interfaces/geom.ts @@ -44,7 +44,7 @@ export interface IGeomService { params: JsonData ): Observable>; get_geometries(params: JsonData): Observable; - // create(obj: IGeomObject) + create(postdata: IGeomObject): Observable; patch(id: number, updatedData: IGeomObject): Observable; // delete(obj: IGeomObject) } diff --git a/frontend/app/services/api-geom.service.ts b/frontend/app/services/api-geom.service.ts index 86f0bd0e0..16d20fff9 100644 --- a/frontend/app/services/api-geom.service.ts +++ b/frontend/app/services/api-geom.service.ts @@ -59,6 +59,12 @@ export class ApiGeomService implements IGeomService { postData: updatedData, }); } + + create( postData: ISitesGroup | ISite): Observable { + return this._cacheService.request("post", `${this.objectType}`, { + postData: postData, + }); + } } @Injectable() From d234330fc9042e51bc1fb57f1fef605ea50a1c34 Mon Sep 17 00:00:00 2001 From: Andria Capai Date: Mon, 20 Feb 2023 15:28:11 +0100 Subject: [PATCH 31/44] feat: delete site_group component Add route back Add site_group from front form component Reviewed-by:andriac [Refs_ticket]: #4 --- .../routes/sites_groups.py | 8 ++++++++ .../monitoring-form.component-g.ts | 20 ++++++++++++++----- .../monitoring-form.component.ts | 4 +--- frontend/app/services/api-geom.service.ts | 5 +++++ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/backend/gn_module_monitoring/routes/sites_groups.py b/backend/gn_module_monitoring/routes/sites_groups.py index f7455d09f..d08933e1d 100644 --- a/backend/gn_module_monitoring/routes/sites_groups.py +++ b/backend/gn_module_monitoring/routes/sites_groups.py @@ -86,9 +86,17 @@ def patch(_id): item = item_schema.load(item_json) item_schema.load(item_json) db.session.add(item) + db.session.commit() return item_schema.dump(item), 201 +@blueprint.route("/sites_groups/", methods=["DELETE"]) +def delete(_id): + item_schema = MonitoringSitesGroupsSchema() + item = TMonitoringSitesGroups.find_by_id(_id) + TMonitoringSitesGroups.query.filter_by(id_g=_id).delete() + db.session.commit() + return item_schema.dump(item), 201 @blueprint.route("/sites_groups", methods=["POST"]) def post(): diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts index d083764e3..8d67501c9 100644 --- a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts +++ b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts @@ -367,16 +367,26 @@ export class MonitoringFormComponentG implements OnInit { onDelete() { this.bDeleteSpinner = true; this._commonService.regularToaster("info", this.msgToaster("Suppression")); - - this.obj.delete().subscribe((objData) => { + // : this.obj.post(this.objForm.value); + this._apiGeomService.delete(this.obj.id).subscribe((del)=>{ + console.log("del obj",del) this.bDeleteSpinner = this.bDeleteModal = false; - this.obj.deleted = true; this.objChanged.emit(this.obj); - setTimeout(() => { this.navigateToParent(); }, 100); - }); + } + + ) + // this.obj.delete().subscribe((objData) => { + // this.bDeleteSpinner = this.bDeleteModal = false; + // this.obj.deleted = true; + // this.objChanged.emit(this.obj); + + // setTimeout(() => { + // this.navigateToParent(); + // }, 100); + // }); } onObjFormValueChange(event) { diff --git a/frontend/app/components/monitoring-form/monitoring-form.component.ts b/frontend/app/components/monitoring-form/monitoring-form.component.ts index 22eb3625a..2713c4fe3 100644 --- a/frontend/app/components/monitoring-form/monitoring-form.component.ts +++ b/frontend/app/components/monitoring-form/monitoring-form.component.ts @@ -286,13 +286,11 @@ export class MonitoringFormComponent implements OnInit { onDelete() { this.bDeleteSpinner = true; - this._commonService.regularToaster('info', this.msgToaster('Suppression')); - this.obj.delete().subscribe((objData) => { this.bDeleteSpinner = this.bDeleteModal = false; this.obj.deleted = true; this.objChanged.emit(this.obj); - + this._commonService.regularToaster('info', this.msgToaster('Suppression')); setTimeout(() => { this.navigateToParent(); }, 100); diff --git a/frontend/app/services/api-geom.service.ts b/frontend/app/services/api-geom.service.ts index 16d20fff9..5bec9da5a 100644 --- a/frontend/app/services/api-geom.service.ts +++ b/frontend/app/services/api-geom.service.ts @@ -65,6 +65,11 @@ export class ApiGeomService implements IGeomService { postData: postData, }); } + + delete(id: number): Observable { + return this._cacheService.request("delete", `${this.objectType}/${id}`); + } + } @Injectable() From c4a82bfd9c9bfff5acc25ad901eabd9b3c0b4b2b Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Tue, 21 Feb 2023 16:50:50 +0100 Subject: [PATCH 32/44] chore(api): removed unused code --- .gitignore | 1 - .../gn_module_monitoring/monitoring/models.py | 35 +++---------------- .../monitoring/schemas.py | 14 +++----- backend/gn_module_monitoring/routes/site.py | 3 -- .../routes/sites_groups.py | 35 +++++-------------- 5 files changed, 17 insertions(+), 71 deletions(-) diff --git a/.gitignore b/.gitignore index 9f3b24fa8..98dd43081 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ config/monitoring/* frontend/assets/*.jpg *.egg-info -**/contrib # Node .npm node_modules diff --git a/backend/gn_module_monitoring/monitoring/models.py b/backend/gn_module_monitoring/monitoring/models.py index 36963fe07..84bd8067d 100644 --- a/backend/gn_module_monitoring/monitoring/models.py +++ b/backend/gn_module_monitoring/monitoring/models.py @@ -2,7 +2,7 @@ Modèles SQLAlchemy pour les modules de suivi """ from sqlalchemy import select, func, and_ -from sqlalchemy.orm import column_property +from sqlalchemy.orm import column_property, ColumnProperty, RelationshipProperty, class_mapper from sqlalchemy.dialects.postgresql import JSONB, UUID from uuid import uuid4 @@ -10,6 +10,7 @@ from utils_flask_sqla_geo.serializers import geoserializable from sqlalchemy.ext.hybrid import hybrid_property +from sqlalchemy.ext.declarative import declared_attr from pypnnomenclature.models import TNomenclatures, BibNomenclaturesTypes from geonature.core.gn_commons.models import TMedias @@ -21,10 +22,6 @@ from geonature.core.gn_monitoring.models import corVisitObserver from gn_module_monitoring.monitoring.queries import Query as MonitoringQuery -import sqlalchemy -from sqlalchemy.orm import class_mapper -from sqlalchemy.ext.declarative import declared_attr - class GenericModel: @declared_attr @@ -57,31 +54,9 @@ def attribute_names(cls): return [ prop.key for prop in class_mapper(cls).iterate_properties - if isinstance(prop, sqlalchemy.orm.ColumnProperty) + if isinstance(prop, ColumnProperty) ] - @classmethod - def get_type_fields(cls): - structure_data = {prop.key:type(prop.expression.type).__name__ for prop in class_mapper(cls).iterate_properties - if isinstance(prop, sqlalchemy.orm.ColumnProperty)} - for prop in class_mapper(cls).iterate_properties: - if isinstance(prop, sqlalchemy.orm.RelationshipProperty): - structure_data[prop.key] = "Select" - return structure_data - - @classmethod - def get_only_field_table(cls): - fields_table = [i.name for i in cls.__table__.columns] - structure_data = {prop.key:type(prop.expression.type).__name__ for prop in class_mapper(cls).iterate_properties - if isinstance(prop, sqlalchemy.orm.ColumnProperty) and prop.key in fields_table} - for prop in class_mapper(cls).iterate_properties: - if isinstance(prop, sqlalchemy.orm.RelationshipProperty): - structure_data[prop.key] = "Select" - return structure_data - - # __table_args__ = {'mysql_engine': 'InnoDB'} - # id = DB.Column(Integer, primary_key=True) - cor_module_type = DB.Table( "cor_module_type", @@ -115,7 +90,7 @@ def get_only_field_table(cls): @serializable -class BibTypeSite(DB.Model,GenericModel): +class BibTypeSite(DB.Model, GenericModel): __tablename__ = "bib_type_site" __table_args__ = {"schema": "gn_monitoring"} query_class = MonitoringQuery @@ -309,7 +284,7 @@ class TMonitoringSites(TBaseSites): ) @serializable -class TMonitoringSitesGroups(DB.Model,GenericModel): +class TMonitoringSitesGroups(DB.Model, GenericModel): __tablename__ = 't_sites_groups' __table_args__ = {'schema': 'gn_monitoring'} query_class = MonitoringQuery diff --git a/backend/gn_module_monitoring/monitoring/schemas.py b/backend/gn_module_monitoring/monitoring/schemas.py index 66fe98ec9..1816d677e 100644 --- a/backend/gn_module_monitoring/monitoring/schemas.py +++ b/backend/gn_module_monitoring/monitoring/schemas.py @@ -2,9 +2,7 @@ import geojson from geonature.utils.env import MA -from marshmallow import Schema, fields, validate, pre_load -from marshmallow_sqlalchemy import SQLAlchemyAutoSchema -from pypnnomenclature.schemas import NomenclatureSchema +from marshmallow import Schema, fields, validate from geonature.core.gn_commons.schemas import MediaSchema from gn_module_monitoring.monitoring.models import ( @@ -37,11 +35,7 @@ class Meta: medias = MA.Nested(MediaSchema) pk = fields.Method("set_pk",dump_only=True) geometry = fields.Method("serialize_geojson", dump_only=True) - # properties = fields.Method("group_properties_geojson") - - # def group_properties_geojson(self, obj): - # return {field: getattr(obj,field) for field in self.fields.keys() if field not in ("geometry","properties")} - + def set_pk(self,obj): return self.Meta.model.get_id() @@ -51,7 +45,7 @@ def serialize_geojson(self, obj): -class MonitoringSitesSchema(SQLAlchemyAutoSchema): +class MonitoringSitesSchema(MA.SQLAlchemyAutoSchema): class Meta: model = TMonitoringSites exclude = ("geom_geojson", "geom") @@ -63,7 +57,7 @@ def serialize_geojson(self, obj): return geojson.dumps(obj.as_geofeature().get("geometry")) -class BibTypeSiteSchema(SQLAlchemyAutoSchema): +class BibTypeSiteSchema(MA.SQLAlchemyAutoSchema): label = fields.Method("get_label_from_type_site") # See if useful in the future: # type_site = fields.Nested(NomenclatureSchema(only=("label_fr",)), dump_only=True) diff --git a/backend/gn_module_monitoring/routes/site.py b/backend/gn_module_monitoring/routes/site.py index 9ea95a045..d4ee778aa 100644 --- a/backend/gn_module_monitoring/routes/site.py +++ b/backend/gn_module_monitoring/routes/site.py @@ -36,9 +36,6 @@ def get_types_site(): @blueprint.route("/sites/types/", methods=["GET"]) def get_type_site_by_id(id_type_site): - # query = BibTypeSite.query.filter_by(id_nomenclature_type_site=id_type_site) - # res = query.first() - # res2 = BibTypeSite.find_by_id() res = BibTypeSite.find_by_id(id_type_site) schema = BibTypeSiteSchema() return schema.dump(res) diff --git a/backend/gn_module_monitoring/routes/sites_groups.py b/backend/gn_module_monitoring/routes/sites_groups.py index d08933e1d..33bcb6bb3 100644 --- a/backend/gn_module_monitoring/routes/sites_groups.py +++ b/backend/gn_module_monitoring/routes/sites_groups.py @@ -1,11 +1,10 @@ -from flask import jsonify, request,json +from flask import jsonify, request from geonature.utils.env import db from gn_module_monitoring.utils.strings.strings import gettext +from marshmallow import ValidationError from sqlalchemy import func from werkzeug.datastructures import MultiDict -from werkzeug.exceptions import HTTPException - from gn_module_monitoring.blueprint import blueprint from gn_module_monitoring.monitoring.models import TMonitoringSites, TMonitoringSitesGroups from gn_module_monitoring.monitoring.schemas import MonitoringSitesGroupsSchema @@ -17,8 +16,6 @@ paginate, sort, ) -from gn_module_monitoring.monitoring.schemas import MonitoringSitesGroupsSchema -from marshmallow import ValidationError from gn_module_monitoring.utils.errors.errorHandler import InvalidUsage @@ -43,7 +40,6 @@ def get_sites_groups(): @blueprint.route("/sites_groups/", methods=["GET"]) def get_sites_group_by_id(id_sites_group: int): schema = MonitoringSitesGroupsSchema() - # result = TMonitoringSitesGroups.query.get_or_404(id_sites_group) result = TMonitoringSitesGroups.find_by_id(id_sites_group) return jsonify(schema.dump(result)) @@ -77,19 +73,17 @@ def patch(_id): if item: fields = TMonitoringSitesGroups.attribute_names() for field in item_json: - if field in (fields): - # getattr(Models.NgBase,field) + if field in fields: setattr(item, field, item_json[field]) - else: - continue else: item = item_schema.load(item_json) item_schema.load(item_json) db.session.add(item) - + db.session.commit() return item_schema.dump(item), 201 + @blueprint.route("/sites_groups/", methods=["DELETE"]) def delete(_id): item_schema = MonitoringSitesGroupsSchema() @@ -98,6 +92,7 @@ def delete(_id): db.session.commit() return item_schema.dump(item), 201 + @blueprint.route("/sites_groups", methods=["POST"]) def post(): item_schema = MonitoringSitesGroupsSchema() @@ -111,19 +106,5 @@ def post(): @blueprint.errorhandler(ValidationError) def handle_validation_error(error): return InvalidUsage( - gettext("item_not_validated").format(error.messages), status_code=422, payload=error.data - ).to_dict() - -# @blueprint.errorhandler(HTTPException) -# def handle_exception(e): -# """Return JSON instead of HTML for HTTP errors.""" -# # start with the correct headers and status code from the error -# response = e.get_response() -# # replace the body with JSON -# response.data = json.dumps({ -# "code": e.code, -# "name": e.name, -# "description": e.description, -# }) -# response.content_type = "application/json" -# return response \ No newline at end of file + gettext("item_not_validated").format(error.messages), status_code=422, payload=error.data + ).to_dict() From 47c825cf5436a0f0462b30bf8ce4d1efcde628a4 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Tue, 21 Feb 2023 16:51:19 +0100 Subject: [PATCH 33/44] style(config): apply formatter --- config/monitoring/generic/config.json | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/config/monitoring/generic/config.json b/config/monitoring/generic/config.json index 092f10feb..dc748a66e 100644 --- a/config/monitoring/generic/config.json +++ b/config/monitoring/generic/config.json @@ -1,21 +1,22 @@ { "tree": { "module": { - "sites_group":{ - "site": { - "visit": { - "observation": null } + "sites_group": { + "site": { + "visit": { + "observation": null + } } } } }, - "synthese" : "__MODULE.B_SYNTHESE", + "synthese": "__MODULE.B_SYNTHESE", "default_display_field_names": { "user": "nom_complet", "nomenclature": "label_fr", "dataset": "dataset_name", "observer_list": "nom_liste", - "taxonomy" : "__MODULE.TAXONOMY_DISPLAY_FIELD_NAME", + "taxonomy": "__MODULE.TAXONOMY_DISPLAY_FIELD_NAME", "taxonomy_list": "nom_liste", "sites_group": "sites_group_name", "habitat": "lb_hab_fr", @@ -23,4 +24,4 @@ "municipality": "nom_com_dept", "site": "base_site_name" } -} +} \ No newline at end of file From 601cb2cba457cc4bec8282a59d70ba4a5630eef0 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Tue, 21 Feb 2023 16:53:17 +0100 Subject: [PATCH 34/44] chore(front): removed unused code & console.log --- frontend/app/class/monitoring-sites-group.ts | 1 - .../components/modules/modules.component.ts | 10 +------ .../monitoring-datatable-g.component.ts | 26 ------------------ .../monitoring-form.component.ts | 5 ---- .../monitoring-sites.component.ts | 27 +++++++++---------- .../monitoring-sitesgroups.component.ts | 12 --------- frontend/app/gnModule.module.ts | 2 -- frontend/app/services/config.service.ts | 2 -- frontend/app/services/data-table.service.ts | 3 --- frontend/app/services/edit-object.service.ts | 4 +-- 10 files changed, 16 insertions(+), 76 deletions(-) diff --git a/frontend/app/class/monitoring-sites-group.ts b/frontend/app/class/monitoring-sites-group.ts index 21ae7f540..96fab297d 100644 --- a/frontend/app/class/monitoring-sites-group.ts +++ b/frontend/app/class/monitoring-sites-group.ts @@ -10,4 +10,3 @@ export const extendedDetailsSiteGroup = { comments: "Commentaires", sites_group_description: "Description", }; -// export type detailsSiteGroups = columnNameSiteGroup | extendedDetailsSiteGroup diff --git a/frontend/app/components/modules/modules.component.ts b/frontend/app/components/modules/modules.component.ts index b538c7afe..56957d49d 100644 --- a/frontend/app/components/modules/modules.component.ts +++ b/frontend/app/components/modules/modules.component.ts @@ -14,8 +14,6 @@ import { AuthService, User } from "@geonature/components/auth/auth.service"; styleUrls: ["./modules.component.css"], }) export class ModulesComponent implements OnInit { - - currentUser: User; description: string; @@ -34,7 +32,7 @@ export class ModulesComponent implements OnInit { private _auth: AuthService, private _dataMonitoringObjectService: DataMonitoringObjectService, private _configService: ConfigService - ) { } + ) {} ngOnInit() { this.bLoading = true; @@ -67,10 +65,4 @@ export class ModulesComponent implements OnInit { this.currentUser["cruved"] = {}; this.currentUser["cruved_objects"] = {}; } - - // onAccessSitesClick(modules) { - // console.log("accès aux sites avec droits ") - // console.log(modules) - // } - } diff --git a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts index f42646b42..b152c85cd 100644 --- a/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts +++ b/frontend/app/components/monitoring-datatable-g/monitoring-datatable-g.component.ts @@ -71,15 +71,10 @@ export class MonitoringDatatableGComponent implements OnInit { ) {} ngOnInit() { - console.log("DataTableComponent colname", this.colsname); - console.log("DataTableComponent rows", this.rows); this.initDatatable(); } initDatatable() { - console.log("Inside initDatatable"); - console.log("this.rows", this.rows); - // IF prefered observable compare to ngOnChanges uncomment this: // this._dataTableService.currentCols.subscribe(newCols => { this.columns = newCols }) this._objService.currentObjectType.subscribe((newObjType) => { @@ -93,13 +88,11 @@ export class MonitoringDatatableGComponent implements OnInit { } onSortEvent($event) { - console.log("onSortEvent, $event", $event); this.filters = { ...this.filters, sort: $event.column.prop, sort_dir: $event.newValue, }; - console.log("onSortEvent, this.filters", this.filters); this.onSort.emit(this.filters); } @@ -108,13 +101,11 @@ export class MonitoringDatatableGComponent implements OnInit { } filterInput($event) { - console.log("filterInput, $event", $event); this.filterSubject.next(); } filter(bInitFilter = false) { // filter all - console.log("Inside DataTable-G , filter()", this.filters); const oldFilters = this.filters; this.filters = Object.keys(oldFilters).reduce(function (r, e) { if (![undefined, "", null].includes(oldFilters[e])) r[e] = oldFilters[e]; @@ -124,17 +115,11 @@ export class MonitoringDatatableGComponent implements OnInit { } onSelectEvent({ selected }) { - console.log("Select Row", selected, this.selected); - console.log("this.table", this.table); - console.log(this.table._internalRows); - console.log("selected[0]", selected[0]); - console.log("selected[0].id", selected[0].id_group_site); const id = selected[0].id_group_site; if (!this.rowStatus) { return; } - console.log("this.rowStatus after check rowStatus", this.rowStatus); this.rowStatus.forEach((status) => { const bCond = status.id === id; @@ -143,9 +128,6 @@ export class MonitoringDatatableGComponent implements OnInit { this.setSelected(); this.rowStatusChange.emit(this.rowStatus); - console.log("after click rowStatus", this.rowStatus); - console.log("after click selected", this.selected); - console.log("after click table", this.table); } setSelected() { @@ -182,9 +164,6 @@ export class MonitoringDatatableGComponent implements OnInit { // } ngOnChanges(changes: SimpleChanges) { - console.log("inside ngOnChanges"); - console.log("changes", changes); - // IF prefered ngOnChanges compare to observable uncomment this: if (changes["rows"] && this.rows && this.rows.length > 0) { this.columns = this._dataTableService.colsTable( @@ -205,9 +184,6 @@ export class MonitoringDatatableGComponent implements OnInit { )); } for (const propName of Object.keys(changes)) { - const chng = changes[propName]; - const cur = chng.currentValue; - const pre = chng.previousValue; switch (propName) { case "rowStatus": this.setSelected(); @@ -216,14 +192,12 @@ export class MonitoringDatatableGComponent implements OnInit { } } navigateToAddChildren(_, rowId) { - console.log("Inside navigateToAddChildren:", rowId); this.addEvent.emit(rowId); this.router.navigate(["create"], { relativeTo: this._Activatedroute, }); } navigateToDetail(row) { - console.log("Inside navigateToDetail:", row); row["id"] = row.pk; this.onDetailsRow.emit(row); } diff --git a/frontend/app/components/monitoring-form/monitoring-form.component.ts b/frontend/app/components/monitoring-form/monitoring-form.component.ts index 2713c4fe3..5e3ca239a 100644 --- a/frontend/app/components/monitoring-form/monitoring-form.component.ts +++ b/frontend/app/components/monitoring-form/monitoring-form.component.ts @@ -55,9 +55,6 @@ export class MonitoringFormComponent implements OnInit { ) {} ngOnInit() { - console.log(this.obj) - // this.obj.moduleCode = "generic" - // this.obj.objectType = "sites_group" this._configService .init(this.obj.moduleCode) .pipe() @@ -68,8 +65,6 @@ export class MonitoringFormComponent implements OnInit { this.queryParams = this._route.snapshot.queryParams || {}; this.bChainInput = this._configService.frontendParams()['bChainInput']; const schema = this.obj.schema(); - - console.log("Init Form this.obj.schema()",schema ) // init objFormsDefinition // meta pour les parametres dynamiques diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts index 23778dca7..5419ab759 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts +++ b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts @@ -11,7 +11,10 @@ import { MonitoringGeomComponent } from "../../class/monitoring-geom-component"; import { setPopup } from "../../functions/popup"; import { GeoJSONService } from "../../services/geojson.service"; import { FormGroup, FormBuilder } from "@angular/forms"; -import { SitesService ,SitesGroupService} from "../../services/api-geom.service"; +import { + SitesService, + SitesGroupService, +} from "../../services/api-geom.service"; import { ObjectService } from "../../services/object.service"; const LIMIT = 10; @@ -32,18 +35,18 @@ export class MonitoringSitesComponent page: IPage; filters = {}; siteGroupLayer: L.FeatureGroup; - @Input() bEdit:boolean; + @Input() bEdit: boolean; objForm: FormGroup; - objectType:string; + objectType: string; constructor( private _sitesGroupService: SitesGroupService, private _siteService: SitesService, - private _objService:ObjectService, + private _objService: ObjectService, private router: Router, private _Activatedroute: ActivatedRoute, private _geojsonService: GeoJSONService, - private _formBuilder: FormBuilder, + private _formBuilder: FormBuilder ) { super(); this.getAllItemsCallback = this.getSitesFromSiteGroupId; @@ -51,12 +54,11 @@ export class MonitoringSitesComponent ngOnInit() { this.objForm = this._formBuilder.group({}); - // this.objectType = this._siteService.addObjectType() - this._objService.changeObjectType(this._siteService.addObjectType()) - this.initSite() + this._objService.changeObjectType(this._siteService.addObjectType()); + this.initSite(); } - initSite(){ + initSite() { this._Activatedroute.params .pipe( map((params) => params["id"] as number), @@ -126,15 +128,12 @@ export class MonitoringSitesComponent seeDetails($event) { console.log("seeDetails", $event); - this._objService.changeObjectTypeParent(this._siteService.editObjectType()) - // this.router.navigate([$event.id_sites_group], { - // relativeTo: this._Activatedroute, - // }); + this._objService.changeObjectTypeParent(this._siteService.editObjectType()); } onSelect($event) {} onObjChanged($event) { - this.initSite() + this.initSite(); } } diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 781199ac6..8111f1899 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -67,13 +67,10 @@ export class MonitoringSitesGroupsComponent } ngOnInit() { - console.log(this.router.url) - console.log(this.location) if (this.router.url == '/monitorings/sites_group'){ this.isAddingForm = false this.initSiteGroup() } else { - console.log(this.objInitForm) this._editService.changeDataSub(this.objInitForm); this.isAddingForm = true this.addComponent() @@ -134,23 +131,14 @@ export class MonitoringSitesGroupsComponent this.router.navigate([$event.id_sites_group], { relativeTo: this._Activatedroute, }); - // if ($event) { - // this.router.navigate([ - // "/monitorings/sites_groups", - // $event.id_sites_group, - // ]); - // console.log(this.sitesGroupsSelected); - // } } addSiteGp($event){ this.isAddingForm = true - console.log("ADD Site Groupe", $event) } onSelect($event) { this.geojsonService.selectSitesGroupLayer($event); } onObjChanged($event) { - console.log($event) } } diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index 78f21ec81..b0bb4ec33 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -34,9 +34,7 @@ import { MatSelectModule } from "@angular/material/select"; import { MatInputModule } from "@angular/material/input"; import { MonitoringSitesGroupsComponent } from "./components/monitoring-sitesgroups/monitoring-sitesgroups.component"; import { DataTableService } from "./services/data-table.service"; -// import { } from "./services/sites_group.service"; import { MonitoringPropertiesGComponent } from "./components/monitoring-properties-g/monitoring-properties-g.component"; -// import { } from "./services/sites.service"; import { GeoJSONService } from "./services/geojson.service"; import { MonitoringSitesComponent } from "./components/monitoring-sites/monitoring-sites.component"; import { MonitoringMapListComponent } from "./components/monitoring-map-list/monitoring-map-list.component"; diff --git a/frontend/app/services/config.service.ts b/frontend/app/services/config.service.ts index 6776e3297..24c0130d4 100644 --- a/frontend/app/services/config.service.ts +++ b/frontend/app/services/config.service.ts @@ -129,9 +129,7 @@ export class ConfigService { schema(moduleCode, objectType, typeSchema = 'all'): Object { moduleCode = moduleCode || 'generic'; - console.log("moduleCode inside config.service",moduleCode) const configObject = this._config[moduleCode][objectType]; - console.log("configObject inside config.service",configObject) // gerer quand les paramètres ont un fonction comme valeur for (const typeSchema of ['generic', 'specific']) { diff --git a/frontend/app/services/data-table.service.ts b/frontend/app/services/data-table.service.ts index 579ead941..8a76099ee 100644 --- a/frontend/app/services/data-table.service.ts +++ b/frontend/app/services/data-table.service.ts @@ -52,7 +52,6 @@ export class DataTableService { } initObjectsStatus(obj, key) { - console.log("obj InitObjectStatus", obj); const objectsStatus = {}; // for (const childrenType of Object.keys(this.obj.children)) { objectsStatus[key] = obj.map((groupSite) => { @@ -63,7 +62,6 @@ export class DataTableService { current: false, }; }); - console.log("objectsStatus", objectsStatus); // } // init site status @@ -87,7 +85,6 @@ export class DataTableService { this.objectsStatus = objectsStatus; this.rowStatus = this.objectsStatus[key]; - console.log("datatable service", this.rowStatus); return [this.objectsStatus, this.rowStatus]; } } diff --git a/frontend/app/services/edit-object.service.ts b/frontend/app/services/edit-object.service.ts index 698086095..fc106678c 100644 --- a/frontend/app/services/edit-object.service.ts +++ b/frontend/app/services/edit-object.service.ts @@ -1,6 +1,6 @@ import { Injectable } from "@angular/core"; import { BehaviorSubject, Observable, of, forkJoin } from "rxjs"; -import { mergeMap, concatMap } from "rxjs/operators"; +import { concatMap } from "rxjs/operators"; import { JsonData } from "../types/jsondata"; @@ -43,7 +43,7 @@ export class EditObjectService { } observables[attribut_name] = this._objService.toForm(elem, properties[attribut_name]); } - console.log(observables) + return forkJoin(observables).pipe( concatMap((formValues_in) => { const formValues = Utils.copy(formValues_in); From 1fc5dfcc2123bc9c2649c44e529dcf9a010f63b3 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Tue, 21 Feb 2023 16:53:47 +0100 Subject: [PATCH 35/44] feat(front): removed display map button As it was ugly --- .../monitoring-map-list.component.html | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/frontend/app/components/monitoring-map-list/monitoring-map-list.component.html b/frontend/app/components/monitoring-map-list/monitoring-map-list.component.html index d5c2325c7..ee93b5280 100644 --- a/frontend/app/components/monitoring-map-list/monitoring-map-list.component.html +++ b/frontend/app/components/monitoring-map-list/monitoring-map-list.component.html @@ -1,18 +1,13 @@
-
+
- +
-
+
\ No newline at end of file From 36ba4e34f93b50fd75940fad32eea7b142d09a5a Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Tue, 21 Feb 2023 16:54:19 +0100 Subject: [PATCH 36/44] refactor(front): remove Object for keys As there is an Angular pipe to get keys and values Also removed console.log Removed unused code --- .../monitoring-properties-g.component.html | 6 ++-- .../monitoring-properties-g.component.ts | 28 ++++++------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html index 4ca680acc..aa74bfb37 100644 --- a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html @@ -41,12 +41,12 @@ - +
- {{ infosColsSiteGroups[fieldName] }} + {{ infosColsSiteGroups[fieldName.key] }} {{ selectedObj[fieldName] }}{{ selectedObj[fieldName.key] }}
diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts index 2581d0fd2..d47a3ef60 100644 --- a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.ts @@ -21,39 +21,29 @@ export class MonitoringPropertiesGComponent implements OnInit { @Input() selectedObj: ISitesGroup; @Input() bEdit: boolean; @Output() bEditChange = new EventEmitter(); - @Input() objectType:string; - Object = Object; + @Input() objectType: string; - // @Input() currentUser; infosColsSiteGroups: typeof extendedDetailsSiteGroup = extendedDetailsSiteGroup; color: string = "white"; dataDetails: ISitesGroup; datasetForm = new FormControl(); - bUpdateSyntheseSpinner = false; - public modalReference; - constructor(private _editService: EditObjectService,private _objService: ObjectService) {} + constructor( + private _editService: EditObjectService, + private _objService: ObjectService + ) {} ngOnInit() { - console.log("selectedObj", this.selectedObj); - console.log("infosColsSiteGroups", this.infosColsSiteGroups); - this._objService.currentObjectTypeParent.subscribe(newObjType => { this.objectType = newObjType }) + this._objService.currentObjectTypeParent.subscribe((newObjType) => { + this.objectType = newObjType; + }); } onEditClick() { this.bEditChange.emit(true); - console.log("edit"); - console.log("obj inside PROPERTIES", this.selectedObj); - this.selectedObj["id"] = this.selectedObj[this.selectedObj.pk] + this.selectedObj["id"] = this.selectedObj[this.selectedObj.pk]; this._editService.changeDataSub(this.selectedObj); } - // ngOnChanges(changes: SimpleChanges) { - // console.log("inside ngOnChanges"); - // console.log("changes", changes); - // if (changes["selectedObj"] && this.selectedObj) { - // console.log(this.selectedObj) - // } - // } } From 05e3fb025fa23bc5d87a80b174d4af5f609c3460 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Tue, 21 Feb 2023 17:12:19 +0100 Subject: [PATCH 37/44] style(front): reformat routes --- frontend/app/gnModule.module.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index b0bb4ec33..1be0b1ec9 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -71,8 +71,7 @@ const routes: Routes = [ path: "", component: MonitoringSitesGroupsComponent, }, - {path:"create", - component:MonitoringSitesGroupsComponent}, + { path: "create", component: MonitoringSitesGroupsComponent }, { path: ":id", component: MonitoringSitesComponent, From 6d1ebb71cc043720378c68e5205af3088850de68 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Wed, 22 Feb 2023 11:20:53 +0100 Subject: [PATCH 38/44] refactor(front): add create component To isolate functionnalities --- .../app/class/monitoring-form-component.ts | 15 ----- .../monitoring-properties-g.component.html | 2 +- .../monitoring-sites.component.ts | 3 + ...onitoring-sitesgroups-create.component.css | 0 ...nitoring-sitesgroups-create.component.html | 4 ++ ...monitoring-sitesgroups-create.component.ts | 23 ++++++++ .../monitoring-sitesgroups.component.html | 24 ++------ .../monitoring-sitesgroups.component.ts | 59 +++++++------------ frontend/app/gnModule.module.ts | 23 ++++++-- 9 files changed, 75 insertions(+), 78 deletions(-) delete mode 100644 frontend/app/class/monitoring-form-component.ts create mode 100644 frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.css create mode 100644 frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.html create mode 100644 frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.ts diff --git a/frontend/app/class/monitoring-form-component.ts b/frontend/app/class/monitoring-form-component.ts deleted file mode 100644 index 535c99806..000000000 --- a/frontend/app/class/monitoring-form-component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ISite, ISitesGroup } from "../interfaces/geom"; -import { Observable } from "rxjs"; -import { JsonData } from "../types/jsondata"; -import { Resp } from "../types/response"; - -type patchPostFunction = ( - id: number, - data: JsonData | ISitesGroup | ISite -) => Observable; -export class MonitoringFormComponent { - protected patchItemCallback: patchPostFunction; - protected postItemCallback: patchPostFunction; - - constructor() {} -} diff --git a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html index aa74bfb37..ebab4aca9 100644 --- a/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html +++ b/frontend/app/components/monitoring-properties-g/monitoring-properties-g.component.html @@ -46,7 +46,7 @@ " > - {{ infosColsSiteGroups[fieldName.key] }} + {{ fieldName.value }} +
+ +
\ No newline at end of file diff --git a/frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.ts b/frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.ts new file mode 100644 index 000000000..4138a321b --- /dev/null +++ b/frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.ts @@ -0,0 +1,23 @@ +import { Component, OnInit } from "@angular/core"; +import { EditObjectService } from "../../services/edit-object.service"; +import { FormGroup, FormBuilder } from "@angular/forms"; +import { ISitesGroup } from "../../interfaces/geom"; + +@Component({ + selector: "monitoring-sitesgroups-create", + templateUrl: "./monitoring-sitesgroups-create.component.html", + styleUrls: ["./monitoring-sitesgroups-create.component.css"], +}) +export class MonitoringSitesGroupsCreateComponent implements OnInit { + siteGroup: ISitesGroup; + form: FormGroup; + constructor( + private _editService: EditObjectService, + private _formBuilder: FormBuilder + ) {} + + ngOnInit() { + this._editService.changeDataSub({}); + this.form = this._formBuilder.group({}); + } +} diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index 778abf048..2ddf3aae0 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -1,22 +1,6 @@
- - -
+ + \ No newline at end of file diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index 8111f1899..88473a04f 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -1,19 +1,14 @@ import { Component, OnInit, Input } from "@angular/core"; -import { Location } from '@angular/common'; import { SitesGroupService } from "../../services/api-geom.service"; import { columnNameSiteGroup } from "../../class/monitoring-sites-group"; import { IPaginated, IPage } from "../../interfaces/page"; -import { - Router, - ActivatedRoute, -} from "@angular/router"; +import { Router, ActivatedRoute } from "@angular/router"; import { columnNameSite } from "../../class/monitoring-site"; import { ISite, ISitesGroup } from "../../interfaces/geom"; import { GeoJSONService } from "../../services/geojson.service"; import { MonitoringGeomComponent } from "../../class/monitoring-geom-component"; import { setPopup } from "../../functions/popup"; import { ObjectService } from "../../services/object.service"; -import { EditObjectService } from "../../services/edit-object.service"; import { FormGroup, FormBuilder } from "@angular/forms"; const LIMIT = 10; @@ -38,10 +33,9 @@ export class MonitoringSitesGroupsComponent // @Input() rows; @Input() colsname; @Input() obj; - objectType:string; - @Input() isAddingForm:boolean; + objectType: string; objForm: FormGroup; - objInitForm:Object= {}; + objInitForm: Object = {}; // siteGroupEmpty={ // "comments" :'', // sites_group_code: string; @@ -54,37 +48,25 @@ export class MonitoringSitesGroupsComponent private _sites_group_service: SitesGroupService, public geojsonService: GeoJSONService, private router: Router, - private _objService:ObjectService, - // IF prefered observable compare to ngOnChanges uncomment this: - // private _dataTableService:DataTableService, - private _editService: EditObjectService, - private location: Location, + private _objService: ObjectService, private _formBuilder: FormBuilder, - private _Activatedroute: ActivatedRoute, // private _routingService: RoutingService - ) { + private _Activatedroute: ActivatedRoute // private _routingService: RoutingService + ) { super(); this.getAllItemsCallback = this.getSitesGroups; } ngOnInit() { - if (this.router.url == '/monitorings/sites_group'){ - this.isAddingForm = false - this.initSiteGroup() - } else { - this._editService.changeDataSub(this.objInitForm); - this.isAddingForm = true - this.addComponent() - } - - } - - addComponent(){ - this.objForm = this._formBuilder.group({}); + this.initSiteGroup(); } - initSiteGroup(){ - this._objService.changeObjectTypeParent(this._sites_group_service.editObjectType()) - this._objService.changeObjectType(this._sites_group_service.addObjectType()) + initSiteGroup() { + this._objService.changeObjectTypeParent( + this._sites_group_service.editObjectType() + ); + this._objService.changeObjectType( + this._sites_group_service.addObjectType() + ); this.getSitesGroups(1); this.geojsonService.getSitesGroupsGeometries( this.onEachFeatureSiteGroups() @@ -127,18 +109,21 @@ export class MonitoringSitesGroupsComponent seeDetails($event) { // TODO: routerLink - this._objService.changeObjectTypeParent(this._sites_group_service.editObjectType()) + this._objService.changeObjectTypeParent( + this._sites_group_service.editObjectType() + ); this.router.navigate([$event.id_sites_group], { relativeTo: this._Activatedroute, }); } - addSiteGp($event){ - this.isAddingForm = true + addSiteGp($event) { + this.router.navigate(["/create"], { + relativeTo: this._Activatedroute, + }); } onSelect($event) { this.geojsonService.selectSitesGroupLayer($event); } - onObjChanged($event) { - } + onObjChanged($event) {} } diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index 1be0b1ec9..5cf2828de 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -41,7 +41,13 @@ import { MonitoringMapListComponent } from "./components/monitoring-map-list/mon import { MonitoringFormComponentG } from "./components/monitoring-form-g/monitoring-form.component-g"; import { EditObjectService } from "./services/edit-object.service"; import { ObjectService } from "./services/object.service"; -import { SitesGroupService,SitesService,ApiGeomService } from "./services/api-geom.service"; +import { + SitesGroupService, + SitesService, + ApiGeomService, +} from "./services/api-geom.service"; +import { MonitoringVisitsComponent } from "./components/monitoring-visits/monitoring-visits.component"; +import { MonitoringSitesGroupsCreateComponent } from "./components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component"; // my module routing const routes: Routes = [ @@ -71,10 +77,16 @@ const routes: Routes = [ path: "", component: MonitoringSitesGroupsComponent, }, - { path: "create", component: MonitoringSitesGroupsComponent }, + { path: "create", component: MonitoringSitesGroupsCreateComponent }, { path: ":id", - component: MonitoringSitesComponent, + // Add new component here + children: [ + { + path: "", + component: MonitoringSitesComponent, + }, + ], }, ], }, @@ -97,7 +109,8 @@ const routes: Routes = [ MonitoringSitesComponent, MonitoringDatatableGComponent, MonitoringPropertiesGComponent, - MonitoringFormComponentG + MonitoringFormComponentG, + MonitoringSitesGroupsCreateComponent, ], imports: [ GN2CommonModule, @@ -127,7 +140,7 @@ const routes: Routes = [ GeoJSONService, EditObjectService, ObjectService, - ApiGeomService + ApiGeomService, ], bootstrap: [ModulesComponent], schemas: [ From ce30a885ec290336649ec320192b35a4a4a6ac8a Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Wed, 22 Feb 2023 11:30:56 +0100 Subject: [PATCH 39/44] chore(front): remove unused services --- frontend/app/services/sites.service.ts | 17 ----------------- frontend/app/services/sites_group.service.ts | 19 ------------------- 2 files changed, 36 deletions(-) delete mode 100644 frontend/app/services/sites.service.ts delete mode 100644 frontend/app/services/sites_group.service.ts diff --git a/frontend/app/services/sites.service.ts b/frontend/app/services/sites.service.ts deleted file mode 100644 index c4a72d66d..000000000 --- a/frontend/app/services/sites.service.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injectable } from "@angular/core"; -import { ApiGeomService, endPoints } from "./api-geom.service"; - -@Injectable() -export class SitesService extends ApiGeomService { - constructor(_cacheService, objectType: endPoints) { - super(_cacheService); - this.objectType = endPoints.sites; - } - addObjectType(): string { - return " un nouveau site"; - } - - editObjectType(): string { - return "le site"; - } -} diff --git a/frontend/app/services/sites_group.service.ts b/frontend/app/services/sites_group.service.ts deleted file mode 100644 index 55f5a5b4b..000000000 --- a/frontend/app/services/sites_group.service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Injectable } from "@angular/core"; -import { ApiGeomService } from "./api-geom.service"; -import { endPoints } from "./api-geom.service"; -@Injectable() -export class SitesGroupService extends ApiGeomService { - constructor(_cacheService) { - super(_cacheService); - this.objectType = endPoints.sites_groups; - console.log(this.objectType); - } - - addObjectType(): string { - return "un nouveau groupe de site"; - } - - editObjectType(): string { - return "le groupe de site"; - } -} From 3c04ec6a9af4d7777df0deca3818275223757bc3 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Wed, 22 Feb 2023 11:34:35 +0100 Subject: [PATCH 40/44] chore(front): removed usused code --- .../monitoring-sitesgroups.component.css | 49 ------------------- frontend/app/services/config.service.ts | 1 - 2 files changed, 50 deletions(-) diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css index 148970149..e69de29bb 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.css @@ -1,49 +0,0 @@ -/* TABLE */ - -.cell-link { - cursor: pointer; -} - -:host::ng-deep .datatable-body-row.active .datatable-row-group { - background-color: rgb(117, 227, 118) !important; -} - -.link:hover { - background-color: rgba(0, 0, 0, 0.2) !important; - transition: background-color 0.5; -} - -.link { - display: inline; - transition: background-color 0.5s; - border-radius: 5px; -} - -.header-filter-span > input { - width: 100%; -} - -.header-sort-span { - /* width: 100%; */ - cursor: pointer; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} - -.header-sort-span:hover { - background-color: rgb(245, 245, 245); -} - -.icon-sort { - font-size: 1.2em; - float: right; -} - -:host::ng-deep .sort-btn { - display: none !important; -} - -.custom-dt { - box-shadow: none !important; -} diff --git a/frontend/app/services/config.service.ts b/frontend/app/services/config.service.ts index 24c0130d4..831edeca0 100644 --- a/frontend/app/services/config.service.ts +++ b/frontend/app/services/config.service.ts @@ -31,7 +31,6 @@ export class ConfigService { } loadConfig(moduleCode) { - console.log(moduleCode) const urlConfig = moduleCode === 'generic' ? `${this.backendModuleUrl()}/config` From fca2f5acaf78a4be1e68e2ba1e1c3b8d8927a6ab Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Wed, 22 Feb 2023 11:38:48 +0100 Subject: [PATCH 41/44] chore(api): remove string package And fix if that cannot be reached --- .../routes/sites_groups.py | 14 ++++------- .../utils/strings/__init__.py | 0 .../utils/strings/en-gb.json | 8 ------ .../utils/strings/strings.py | 25 ------------------- 4 files changed, 5 insertions(+), 42 deletions(-) delete mode 100644 backend/gn_module_monitoring/utils/strings/__init__.py delete mode 100644 backend/gn_module_monitoring/utils/strings/en-gb.json delete mode 100644 backend/gn_module_monitoring/utils/strings/strings.py diff --git a/backend/gn_module_monitoring/routes/sites_groups.py b/backend/gn_module_monitoring/routes/sites_groups.py index 33bcb6bb3..8ebb8d3fd 100644 --- a/backend/gn_module_monitoring/routes/sites_groups.py +++ b/backend/gn_module_monitoring/routes/sites_groups.py @@ -1,6 +1,5 @@ from flask import jsonify, request from geonature.utils.env import db -from gn_module_monitoring.utils.strings.strings import gettext from marshmallow import ValidationError from sqlalchemy import func from werkzeug.datastructures import MultiDict @@ -70,13 +69,10 @@ def patch(_id): item_schema = MonitoringSitesGroupsSchema() item_json = request.get_json() item = TMonitoringSitesGroups.find_by_id(_id) - if item: - fields = TMonitoringSitesGroups.attribute_names() - for field in item_json: - if field in fields: - setattr(item, field, item_json[field]) - else: - item = item_schema.load(item_json) + fields = TMonitoringSitesGroups.attribute_names() + for field in item_json: + if field in fields: + setattr(item, field, item_json[field]) item_schema.load(item_json) db.session.add(item) @@ -106,5 +102,5 @@ def post(): @blueprint.errorhandler(ValidationError) def handle_validation_error(error): return InvalidUsage( - gettext("item_not_validated").format(error.messages), status_code=422, payload=error.data + "Fields cannot be validated, message : {}".format(error.messages), status_code=422, payload=error.data ).to_dict() diff --git a/backend/gn_module_monitoring/utils/strings/__init__.py b/backend/gn_module_monitoring/utils/strings/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/gn_module_monitoring/utils/strings/en-gb.json b/backend/gn_module_monitoring/utils/strings/en-gb.json deleted file mode 100644 index 02dc5a53c..000000000 --- a/backend/gn_module_monitoring/utils/strings/en-gb.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "item_name_exists": "An item with name '{}' already exists.", - "item_error_inserting": "An error occurred while inserting the item.", - "item_not_found": "An item cannot be found.", - "item_deleted": "Item deleted.", - "item_not_validated" :"Validation fields not pass , message : {}", - "field_not_valid":"The field '{}' from request body is not valid see the model {} '" -} \ No newline at end of file diff --git a/backend/gn_module_monitoring/utils/strings/strings.py b/backend/gn_module_monitoring/utils/strings/strings.py deleted file mode 100644 index b43e719f4..000000000 --- a/backend/gn_module_monitoring/utils/strings/strings.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -libs.strings - -By default, uses `en-gb.json` file inside the `strings` top-level folder. - -If language changes, set `libs.strings.default_locale` and run `libs.strings.refresh()`. -""" -import json,os - -default_locale = "en-gb" -cached_strings = {} -dir = os.path.dirname(os.path.realpath(__file__)) -# parent_dir = os.path.abspath(os.path.join(dir, os.pardir)) -def refresh(): - print("Refreshing...") - global cached_strings - with open(os.path.join(dir,f"{default_locale}.json")) as f: - cached_strings = json.load(f) - - -def gettext(name): - return cached_strings[name] - - -refresh() From 7456009b21e117f031aa55764f7e8682c4d127aa Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Wed, 22 Feb 2023 11:48:29 +0100 Subject: [PATCH 42/44] chore(api): removed unused comment --- backend/gn_module_monitoring/utils/errors/errorHandler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/gn_module_monitoring/utils/errors/errorHandler.py b/backend/gn_module_monitoring/utils/errors/errorHandler.py index 92401d02d..a10b13987 100644 --- a/backend/gn_module_monitoring/utils/errors/errorHandler.py +++ b/backend/gn_module_monitoring/utils/errors/errorHandler.py @@ -13,7 +13,6 @@ def __init__(self, message, status_code=None, payload=None): def to_dict(self): rv = {} - # rv['payload'] = dict(self.payload or ()) rv["payload"] = self.payload rv["message"] = self.message rv["status_code"] = self.status_code From c3b5b7b5f05b6ba2905b5d77d7f68ed8d4639c19 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Wed, 22 Feb 2023 11:48:47 +0100 Subject: [PATCH 43/44] chore(front): removed console.log and comments --- .../monitoring-form.component-g.ts | 48 +++---------------- 1 file changed, 6 insertions(+), 42 deletions(-) diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts index 8d67501c9..c993c5026 100644 --- a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts +++ b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts @@ -66,15 +66,8 @@ export class MonitoringFormComponentG implements OnInit { ) {} ngOnInit() { - // console.log(this.obj); - // this.obj.moduleCode = "generic"; - // this.obj.objectType = "sites_group"; - console.log(this.obj); this._editService.currentData.subscribe((dataToEdit) => { this.obj = dataToEdit; - console.log("inside subscribe FORM", this.obj); - // this.obj.moduleCode = "generic"; - // this.obj.objectType = "sites_group"; this.obj.bIsInitialized = true; this._configService .init(this.obj.moduleCode) @@ -91,7 +84,6 @@ export class MonitoringFormComponentG implements OnInit { this.obj.moduleCode, this.obj.objectType ); - console.log(schema); this.obj[this.obj.moduleCode] = schema; // const schema = this.obj.schema(); @@ -107,7 +99,6 @@ export class MonitoringFormComponentG implements OnInit { parents: this.obj.parents, }; - console.log(this.meta); this.objFormsDefinition = this._dynformService .formDefinitionsdictToArray(schema, this.meta) .filter((formDef) => formDef.type_widget) @@ -190,10 +181,8 @@ export class MonitoringFormComponentG implements OnInit { } this.setQueryParams(); - console.log("Init Form", this.obj); // pour donner la valeur de l'objet au formulaire this._editService.formValues(this.obj).subscribe((formValue) => { - console.log(formValue); this.objForm.patchValue(formValue); this.setDefaultFormValue(); this.dataForm = formValue; @@ -296,8 +285,8 @@ export class MonitoringFormComponentG implements OnInit { */ navigateToParent() { this.bEditChange.emit(false); // patch bug navigation - this._router.navigateByUrl('/monitorings/sites_group') - + this._router.navigateByUrl("/monitorings/sites_group"); + // this.obj.navigateToParent(); } @@ -308,13 +297,12 @@ export class MonitoringFormComponentG implements OnInit { /** TODO améliorer site etc.. */ onSubmit() { - console.log(this.obj); const { patch_update, ...sendValue } = this.dataForm; const action = this.obj.id ? // ? this.obj.patch(this.objForm.value) // : this.obj.post(this.objForm.value); this._apiGeomService.patch(this.obj.id, sendValue) - : this._apiGeomService.create(sendValue) + : this._apiGeomService.create(sendValue); const actionLabel = this.obj.id ? "Modification" : "Création"; action.subscribe((objData) => { this._commonService.regularToaster( @@ -330,13 +318,10 @@ export class MonitoringFormComponentG implements OnInit { } if (this.bChainInput) { - console.log('bChainInput') this.resetObjForm(); } else if (this.bAddChildren) { - console.log('bAddChildren') this.navigateToAddChildren(); } else { - console.log('this._configService.configModuleObjectParam') if ( this._configService.configModuleObjectParam( this.obj.moduleCode, @@ -367,33 +352,20 @@ export class MonitoringFormComponentG implements OnInit { onDelete() { this.bDeleteSpinner = true; this._commonService.regularToaster("info", this.msgToaster("Suppression")); - // : this.obj.post(this.objForm.value); - this._apiGeomService.delete(this.obj.id).subscribe((del)=>{ - console.log("del obj",del) + // : this.obj.post(this.objForm.value); + this._apiGeomService.delete(this.obj.id).subscribe((del) => { this.bDeleteSpinner = this.bDeleteModal = false; this.objChanged.emit(this.obj); setTimeout(() => { this.navigateToParent(); }, 100); - } - - ) - // this.obj.delete().subscribe((objData) => { - // this.bDeleteSpinner = this.bDeleteModal = false; - // this.obj.deleted = true; - // this.objChanged.emit(this.obj); - - // setTimeout(() => { - // this.navigateToParent(); - // }, 100); - // }); + }); } onObjFormValueChange(event) { // let {id_module,medias, ...rest} = this.objForm.value; // this.dataForm = rest this.dataForm = this.objForm.value; - console.log(this.dataForm); const change = this._configService.change( this.obj.moduleCode, this.obj.objectType @@ -421,12 +393,4 @@ export class MonitoringFormComponentG implements OnInit { // patch pour recalculers this.procesPatchUpdateForm(); } - - ngOnChanges(changes: SimpleChanges) { - console.log("inside ngOnChanges"); - console.log("changes", changes); - if (changes["obj"] && this.obj) { - console.log(this.obj); - } - } } From fb0c29ae4ff42b56e5bb834cf6834ecb66d30848 Mon Sep 17 00:00:00 2001 From: Maxime Vergez Date: Fri, 24 Feb 2023 14:54:55 +0100 Subject: [PATCH 44/44] chore(api): removed unused code and log --- .../components/monitoring-sites/monitoring-sites.component.ts | 4 ---- frontend/app/services/api-geom.service.ts | 1 - 2 files changed, 5 deletions(-) diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts index b2ddddad4..00b9cd752 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts +++ b/frontend/app/components/monitoring-sites/monitoring-sites.component.ts @@ -5,7 +5,6 @@ import { tap, map, mergeMap } from "rxjs/operators"; import * as L from "leaflet"; import { ISite, ISitesGroup } from "../../interfaces/geom"; import { IPage, IPaginated } from "../../interfaces/page"; -// import { } from "../../services/sites_group.service"; import { columnNameSite } from "../../class/monitoring-site"; import { MonitoringGeomComponent } from "../../class/monitoring-geom-component"; import { setPopup } from "../../functions/popup"; @@ -127,15 +126,12 @@ export class MonitoringSitesComponent } seeDetails($event) { - console.log("seeDetails", $event); this._objService.changeObjectTypeParent(this._siteService.editObjectType()); this.router.navigate([`sites/${$event.id_base_site}`], { relativeTo: this._Activatedroute, }); } - onSelect($event) {} - onObjChanged($event) { this.initSite(); } diff --git a/frontend/app/services/api-geom.service.ts b/frontend/app/services/api-geom.service.ts index 5bec9da5a..296913ebf 100644 --- a/frontend/app/services/api-geom.service.ts +++ b/frontend/app/services/api-geom.service.ts @@ -23,7 +23,6 @@ export class ApiGeomService implements IGeomService { init() { this.objectType = endPoints.sites_groups; - console.log(this.objectType); } get( page: number = 1,