Skip to content

Commit

Permalink
SYNTHESE : add customizable fields to the list - close #2946
Browse files Browse the repository at this point in the history
  • Loading branch information
TheoLechemia committed Mar 14, 2024
1 parent 59a5028 commit c4c362f
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 22 deletions.
5 changes: 4 additions & 1 deletion backend/geonature/core/gn_synthese/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from werkzeug.exceptions import Forbidden, NotFound, BadRequest, Conflict
from werkzeug.datastructures import MultiDict
from sqlalchemy import distinct, func, desc, asc, select, case
from sqlalchemy.orm import joinedload, lazyload, selectinload, contains_eager
from geojson import FeatureCollection, Feature
import sqlalchemy as sa
from sqlalchemy.orm import load_only, aliased, Load, with_expression
Expand Down Expand Up @@ -148,7 +149,9 @@ def get_observations_for_web(permissions):

# Get Column Frontend parameter to return only the needed columns
param_column_list = {
col["prop"] for col in current_app.config["SYNTHESE"]["LIST_COLUMNS_FRONTEND"]
col["prop"]
for col in current_app.config["SYNTHESE"]["LIST_COLUMNS_FRONTEND"]
+ current_app.config["SYNTHESE"]["ADDITIONAL_COLUMNS_FRONTEND"]
}
# Init with compulsory columns
columns = []
Expand Down
13 changes: 10 additions & 3 deletions backend/geonature/tests/test_synthese.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,11 @@ class CustomRequiredConverter(GeoModelConverter):

def _add_column_kwargs(self, kwargs, column):
super()._add_column_kwargs(kwargs, column)
default_cols = map(lambda col: col["prop"], config["SYNTHESE"]["LIST_COLUMNS_FRONTEND"])
default_cols = map(
lambda col: col["prop"],
config["SYNTHESE"]["LIST_COLUMNS_FRONTEND"]
+ config["SYNTHESE"]["ADDITIONAL_COLUMNS_FRONTEND"],
)
required_cols = list(default_cols) + MANDATORY_COLUMNS
kwargs["required"] = column.name in required_cols

Expand All @@ -135,8 +139,6 @@ class VSyntheseForWebAppSchema(GeoAlchemyAutoSchema):

class Meta:
model = VSyntheseForWebApp
feature_geometry = "the_geom_4326"
sqla_session = db.session
model_converter = CustomRequiredConverter


Expand Down Expand Up @@ -175,6 +177,10 @@ def test_required_fields_and_format(self, app, users):
{"prop": "count_min_max", "name": "Dénombrement"},
{"prop": "nom_vern_or_lb_nom", "name": "Taxon"},
]

app.config["SYNTHESE"]["ADDITIONAL_COLUMNS_FRONTEND"] += [
{"prop": "lb_nom", "name": "Nom scientifique"}
]
url_ungrouped = url_for("gn_synthese.get_observations_for_web")
set_logged_user(self.client, users["admin_user"])
resp = self.client.get(url_ungrouped)
Expand Down Expand Up @@ -229,6 +235,7 @@ def test_get_observations_for_web(self, app, users, synthese_data, taxon_attribu
"name": "Cdnom",
}
]
# schema["properties"]["observations"]["items"]["required"] =
# test on synonymy and taxref attrs
filters = {
"cd_ref": [taxon_attribut.bib_nom.cd_ref],
Expand Down
10 changes: 3 additions & 7 deletions backend/geonature/utils/config_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,15 +355,11 @@ class Synthese(Schema):

# --------------------------------------------------------------------
# SYNTHESE - OBSERVATIONS LIST
# Listes des champs renvoyés par l'API synthese '/synthese'
# Si on veut afficher des champs personnalisés dans le frontend (paramètre LIST_COLUMNS_FRONTEND) il faut
# d'abbord s'assurer que ces champs sont bien renvoyé par l'API !
# Colonnes affichées par défaut sur la liste des résultats de la synthese
# Champs disponibles: tous ceux de la vue 'v_synthese_for_web_app
COLUMNS_API_SYNTHESE_WEB_APP = fields.List(
fields.String, load_default=DEFAULT_COLUMNS_API_SYNTHESE
)
# Colonnes affichées sur la liste des résultats de la sytnthese
LIST_COLUMNS_FRONTEND = fields.List(fields.Dict, load_default=DEFAULT_LIST_COLUMN)
# Colonnes affichables sur la liste des résultats de la synthese via la modale de selection des colonnes
ADDITIONAL_COLUMNS_FRONTEND = fields.List(fields.Dict, load_default=[])

# --------------------------------------------------------------------
# SYNTHESE - DOWNLOADS (AKA EXPORTS)
Expand Down
10 changes: 9 additions & 1 deletion config/default_config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -269,15 +269,23 @@ MEDIA_CLEAN_CRONTAB = "0 1 * * *"

# Colonne à afficher par défaut sur la liste des résultats de la synthese
# Choisir le champ 'prop' parmis les colonnes suivantes :
# id (=id_synthese), date_min, cd_nom, lb_nom, nom_vern_or_lb_nom,
# id_synthese, date_min, cd_nom, lb_nom, nom_vern_or_lb_nom,
# observers, dataset_name, url_source, count_min_max
# La liste des colonnes affichables est celle de la vue `gn_synthese.v_synthese_for_export`+ `nom_vern_or_lb_nom` et `count_min_max`
LIST_COLUMNS_FRONTEND = [
{ prop = "nom_vern_or_lb_nom", name = "Taxon" },
{ prop = "date_min", name = "Date début" },
{ prop = "observers", name = "Observateurs" },
{ prop = "dataset_name", name = "Jeu de données" }
]

# Colonnes affichables dans la liste des résulats, mais masquées par default
# Possibilité de les ajouter en cliquant sur la route crantée en haut de la liste
# La liste des colonnes affichables est celle de la vue `gn_synthese.v_synthese_for_export`
ADDITIONAL_COLUMNS_FRONTEND = [
{ prop = "lb_nom", name = "Nom scientifique" },
]

# Nombre de résultats à afficher pour la recherche autocompletée de taxon
TAXON_RESULT_NUMBER = 20

Expand Down
6 changes: 6 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
CHANGELOG
=========

## 2.14.1 (unrealesed)

🚀 Nouveautés

- [Synthèse] Possibilité d'ajouter des champs supplémentaires à la liste de résultats via le paramètre `ADDITIONAL_COLUMNS_FRONTEND`. Ces champs sont masqués par défaut et controlables depuis l'interface (#2946)

2.14.0 - Talpa europaea 👓 (2024-02-28)
---------------------------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#table
class="material striped margin-top-xs table-size expandable"
[rows]="mapListService.tableData"
[columns]="SYNTHESE_CONFIG.LIST_COLUMNS_FRONTEND"
[columns]="defaultColumns"
[columnMode]="'force'"
[headerHeight]="50"
[footerHeight]="35"
Expand All @@ -19,6 +19,18 @@
(select)="mapListService.onRowSelect($event)"
>
<ngx-datatable-column [maxWidth]="5">
<ng-template ngx-datatable-header-template>
<i
id="dropdownMenuButton"
class="fa fa-cog clickable"
aria-hidden="true"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
matTooltip="{{ 'List.Columns' | translate }}"
(click)="openModalCol($event, modalCol)"
></i>
</ng-template>
<ng-template
let-row="row"
ngx-datatable-cell-template
Expand Down Expand Up @@ -59,7 +71,7 @@

<!-- cellClass is use for test, the "data-qa" attr do not work because the html is generated -->
<ngx-datatable-column
*ngFor="let col of SYNTHESE_CONFIG.LIST_COLUMNS_FRONTEND"
*ngFor="let col of defaultColumns"
[maxWidth]="col.max_width"
[name]="col.name"
[prop]="col.prop"
Expand Down Expand Up @@ -93,12 +105,33 @@
<mat-icon>file_download</mat-icon>
</button>

<!-- <pnx-modal-download [pathDownload]="exportRoute " [queryString]="queyrStringDownload " [exportFormat]="SYNTHESE_CONFIG.EXPORT_FORMAT "
(buttonClicked)="setQueryString() ">
</pnx-modal-download> -->
<ng-template
#modalCol
let-c="close"
let-d="dismiss"
>
<div class="modal-header">
<h4>{{ 'List.DisplayColumns' | translate }}</h4>
</div>
<div class="modal-body">
<div
class="form-check"
*ngFor="let col of availableColumns"
>
<input
class="form-check-input"
type="checkbox"
[id]="col.name"
(click)="toggleColumnNames(col)"
[checked]="col.checked"
/>

<!-- MODAL INFO OBS -->
<!-- <ng-template #modalInfoObs let-c="close " let-d="dismiss">
<pnx-synthese-modal-info-obs></pnx-synthese-modal-info-obs>
</ng-template> -->
<label
[attr.for]="col.name"
class="form-check-label"
>
{{ col.name | readablePropertie }}
</label>
</div>
</div>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { ColumnMode } from '@swimlane/ngx-datatable';
import { CruvedStoreService } from '@geonature_common/service/cruved-store.service';
import { SyntheseInfoObsComponent } from '@geonature/shared/syntheseSharedModule/synthese-info-obs/synthese-info-obs.component';
import { ConfigService } from '@geonature/services/config.service';
import { FormArray, FormControl } from '@angular/forms';
@Component({
selector: 'pnx-synthese-list',
templateUrl: 'synthese-list.component.html',
Expand All @@ -39,6 +40,8 @@ export class SyntheseListComponent implements OnInit, OnChanges, AfterContentChe
public inpnMapUrl: string;
public downloadMessage: string;
public ColumnMode: ColumnMode;
public availableColumns: Array<any> = [];
public defaultColumns: Array<any> = [];
//input to resize datatable on searchbar toggle
@Input() searchBarHidden: boolean;
@Input() inputSyntheseData: GeoJSON;
Expand All @@ -60,6 +63,8 @@ export class SyntheseListComponent implements OnInit, OnChanges, AfterContentChe
const h = document.documentElement.clientHeight;
this.rowNumber = Math.trunc(h / 37);

this.initListColumns();

// On map click, select on the list a change the page
this.mapListService.onMapClik$.subscribe((ids) => {
this.resetSorting();
Expand Down Expand Up @@ -104,6 +109,20 @@ export class SyntheseListComponent implements OnInit, OnChanges, AfterContentChe
this.table.sorts = [];
}

initListColumns() {
this.defaultColumns = this.SYNTHESE_CONFIG.LIST_COLUMNS_FRONTEND;
let allColumnsTemp = [
...this.SYNTHESE_CONFIG.LIST_COLUMNS_FRONTEND,
...this.SYNTHESE_CONFIG.ADDITIONAL_COLUMNS_FRONTEND,
];
this.availableColumns = allColumnsTemp.map((col) => {
col['checked'] = this.defaultColumns.some((defcol) => {
return defcol.name == col.name;
});
return col;
});
}

/**
* Restore previous selected rows when sort state return to 'undefined'.
* With ngx-datable sortType must be 'multi' to use 3 states : asc, desc and undefined !
Expand Down Expand Up @@ -143,6 +162,10 @@ export class SyntheseListComponent implements OnInit, OnChanges, AfterContentChe
modalRef.componentInstance.useFrom = 'synthese';
}

openModalCol($event, modal) {
this.ngbModal.open(modal);
}

openDownloadModal() {
this.ngbModal.open(SyntheseModalDownloadComponent, {
size: 'lg',
Expand All @@ -161,6 +184,11 @@ export class SyntheseListComponent implements OnInit, OnChanges, AfterContentChe
return [pad(d.getDate()), pad(d.getMonth() + 1), d.getFullYear()].join('-');
}

toggleColumnNames(col) {
col.checked = !col.checked;
this.defaultColumns = this.availableColumns.filter((col) => col.checked);
}

ngOnChanges(changes) {
if (changes.inputSyntheseData && changes.inputSyntheseData.currentValue) {
// reset page 0 when new data appear
Expand Down

0 comments on commit c4c362f

Please sign in to comment.