Skip to content

Commit

Permalink
Merge branch 'develop' into 2.15/update-dependences
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierre-Narcisi authored Oct 30, 2024
2 parents 6926d98 + b76a751 commit 2acf4c4
Show file tree
Hide file tree
Showing 55 changed files with 968 additions and 892 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.14.2
2.15.0
15 changes: 13 additions & 2 deletions backend/geonature/core/gn_synthese/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from pypnnomenclature.models import BibNomenclaturesTypes, TNomenclatures
from werkzeug.exceptions import Forbidden, NotFound, BadRequest, Conflict
from werkzeug.datastructures import MultiDict
from sqlalchemy import distinct, func, desc, asc, select, case
from sqlalchemy import distinct, func, desc, asc, select, case, or_
from sqlalchemy.orm import joinedload, lazyload, selectinload, contains_eager
from geojson import FeatureCollection, Feature
import sqlalchemy as sa
Expand Down Expand Up @@ -1529,7 +1529,18 @@ def list_all_reports(permissions):

# Filter by id_role for 'pin' type only or if my_reports is true
if type_name == "pin" or my_reports:
query = query.where(TReport.id_role == g.current_user.id_role)
query = query.where(
or_(
TReport.id_role == g.current_user.id_role,
TReport.id_synthese.in_(
select(TReport.id_synthese).where(TReport.id_role == g.current_user.id_role)
),
TReport.synthese.has(Synthese.id_digitiser == g.current_user.id_role),
TReport.synthese.has(
Synthese.cor_observers.any(User.id_role == g.current_user.id_role)
),
)
)

# On vérifie les permissions en lecture sur la synthese
synthese_query = select(Synthese.id_synthese).select_from(Synthese)
Expand Down
11 changes: 6 additions & 5 deletions backend/geonature/tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -989,8 +989,9 @@ def reports_data(users, synthese_data):
data = []

# do not commit directly on current transaction, as we want to rollback all changes at the end of tests
def create_report(id_synthese, id_role, content, id_type, deleted):
def create_report(id_synthese, id_report, id_role, content, id_type, deleted):
new_report = TReport(
id_report=id_report,
id_synthese=id_synthese,
id_role=id_role,
content=content,
Expand All @@ -1015,10 +1016,10 @@ def create_report(id_synthese, id_role, content, id_type, deleted):
)
with db.session.begin_nested():
reports = [
(ids[0], users["admin_user"].id_role, "comment1", discussionId, False),
(ids[1], users["admin_user"].id_role, "comment1", alertId, False),
(ids[2], users["user"].id_role, "a_comment1", discussionId, True),
(ids[3], users["user"].id_role, "b_comment1", discussionId, True),
(ids[0], 10001, users["admin_user"].id_role, "comment1", discussionId, False),
(ids[1], 10002, users["admin_user"].id_role, "comment1", alertId, False),
(ids[2], 10003, users["user"].id_role, "a_comment1", discussionId, True),
(ids[3], 10004, users["user"].id_role, "b_comment1", discussionId, True),
]
for id_synthese, *args in reports:
data.append(create_report(id_synthese, *args))
Expand Down
20 changes: 12 additions & 8 deletions backend/geonature/tests/test_reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,19 +219,23 @@ def test_list_all_reports(
assert isinstance(response.json["items"], list)
assert len(response.json["items"]) >= 0

ids = [s.id_synthese for s in synthese_data.values()]
# TEST WITH MY_REPORTS TRUE
set_logged_user(self.client, users["user"])
response = self.client.get(url_for(url, type="discussion", my_reports="true"))
assert response.status_code == 200
items = response.json["items"]
# Check that all items belong to the current user
id_role = users["user"].id_role
nom_complet = users["user"].nom_complet
assert all(
item["id_role"] == id_role and item["user"]["nom_complet"] == nom_complet
for item in items
)
expected_ids = [
10001, # User is observer
10003, # User is report owner
10004, # User is report owner
]
# Missing cases:
# - User is digitiser
# - User has post a report in the same synthese
# They involve adding data to the `synthese_data` fixture, which could cause other tests to fail.
item_ids = [item["id_report"] for item in items]
item_ids.sort()
assert expected_ids == item_ids

# Test undefined type
response = self.client.get(url_for(url, type="UNKNOW-REPORT-TYPE", my_reports="true"))
Expand Down
1 change: 1 addition & 0 deletions backend/geonature/utils/config_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ class TaxonSheet(Schema):
# --------------------------------------------------------------------
# SYNTHESE - TAXON_SHEET
ENABLE_PROFILE = fields.Boolean(load_default=True)
ENABLE_TAXONOMY = fields.Boolean(load_default=True)


class Synthese(Schema):
Expand Down
2 changes: 1 addition & 1 deletion backend/requirements-dependencies.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ pypnnomenclature>=1.6.4,<2
pypn_habref_api>=0.4.1,<1
utils-flask-sqlalchemy-geo>=0.3.2,<1
utils-flask-sqlalchemy>=0.4.1,<1
taxhub==2.0.0rc1
taxhub==2.0.0
pypn-ref-geo>=1.5.3,<2
8 changes: 7 additions & 1 deletion backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ bokeh==3.4.1
# via -r requirements-common.in
brotli==1.1.0
# via fonttools
cairocffi==1.7.0
# via
# cairosvg
# weasyprint
cairosvg==2.7.1
# via weasyprint
celery[redis]==5.4.0
# via -r requirements-common.in
certifi==2024.8.30
Expand Down Expand Up @@ -301,7 +307,7 @@ sqlalchemy==1.4.54
# utils-flask-sqlalchemy
# utils-flask-sqlalchemy-geo
# wtforms-sqlalchemy
taxhub==2.0.0rc1
taxhub==2.0.0
# via
# -r requirements-dependencies.in
# pypnnomenclature
Expand Down
2 changes: 2 additions & 0 deletions config/default_config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ MEDIA_CLEAN_CRONTAB = "0 1 * * *"
# Options dédiées à la fiche taxon
# Permet d'activer ou non la section "Profile"
ENABLE_PROFILE = true
# Permet d'activer ou non la section "Taxonomy"
ENABLE_TAXONOMY = true

# Gestion des demandes d'inscription
[ACCOUNT_MANAGEMENT]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ <h5 class="my-3 ml-3">
[mailCustomSubject]="config.VALIDATION.MAIL_SUBJECT"
[mailCustomBody]="config.VALIDATION.MAIL_BODY"
useFrom="validation"
[selectedTab]="tab"
>
<button
class="status-badge"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class ValidationModalInfoObsComponent implements OnInit {

@Input() id_synthese: any;
@Input() uuidSynthese: any;
@Input() tab: string = 'details';
@Output() modifiedStatus = new EventEmitter();
@Output() valDate = new EventEmitter();
@Output() onCloseModal = new EventEmitter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { SyntheseFormService } from '@geonature_common/form/synthese-form/synthe
import { SyntheseDataService } from '@geonature_common/form/synthese-form/synthese-data.service';
import { find, isEmpty, get, findIndex } from 'lodash';
import { ConfigService } from '@geonature/services/config.service';
import { Location } from '@angular/common';

@Component({
selector: 'pnx-validation-synthese-list',
Expand All @@ -42,6 +43,7 @@ export class ValidationSyntheseListComponent implements OnInit, OnChanges, After

@Input() inputSyntheseData: Array<any>;
@Input() validationStatus: Array<any>;
@Input() selectedTab: string;
@ViewChild('table') table: DatatableComponent;
@Output() pageChange: EventEmitter<number>;
@Output() displayAll = new EventEmitter<any>();
Expand All @@ -61,7 +63,8 @@ export class ValidationSyntheseListComponent implements OnInit, OnChanges, After
public ref: ChangeDetectorRef,
private _ms: MapService,
public formService: SyntheseFormService,
public config: ConfigService
public config: ConfigService,
private location: Location
) {}

ngOnInit() {
Expand Down Expand Up @@ -252,6 +255,9 @@ export class ValidationSyntheseListComponent implements OnInit, OnChanges, After
modalRef.componentInstance.validationStatus = this.validationStatus;
modalRef.componentInstance.currentValidationStatus = row.nomenclature_valid_status;
modalRef.componentInstance.mapListService = this.mapListService;
if (this.selectedTab) {
modalRef.componentInstance.tab = this.selectedTab;
}
modalRef.componentInstance.modifiedStatus.subscribe((modifiedStatus) => {
for (let obs in this.mapListService.tableData) {
if (this.mapListService.tableData[obs].id_synthese == modifiedStatus.id_synthese) {
Expand All @@ -261,10 +267,18 @@ export class ValidationSyntheseListComponent implements OnInit, OnChanges, After
}
}
});
modalRef.componentInstance.onCloseModal.subscribe(() => {
// to refresh mapListService table UI
this.updateReports();
});
modalRef.result.then(
(result) => {
this.updateReports();
this.idSynthese = null;
this.location.replaceState(`/validation`);
},
(reason) => {
this.updateReports();
this.idSynthese = null;
this.location.replaceState(`/validation`);
}
);
modalRef.componentInstance.valDate.subscribe((data) => {
for (let obs in this.mapListService.selectedRow) {
this.mapListService.selectedRow[obs]['validation_date'] = data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
[idSynthese]="idSynthese"
[inputSyntheseData]="_mapListService.tableData"
[validationStatus]="validationStatus"
[selectedTab]="selectedTab"
></pnx-validation-synthese-list>

<!-- select only observations with awaiting validation status
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class ValidationComponent implements OnInit {
public validationStatus;
public searchBarHidden: boolean = true;
public idSynthese: any;

public selectedTab: string;
public isCollapseValidationNavBar = false;

constructor(
Expand Down Expand Up @@ -44,6 +44,7 @@ export class ValidationComponent implements OnInit {
);
this._commonService.translateToaster('info', 'Les 100 dernières observations');
this.idSynthese = this._route.snapshot.paramMap.get('id_synthese');
this.selectedTab = this._route.snapshot.paramMap.get('tab');
}

getStatusNames() {
Expand Down
3 changes: 2 additions & 1 deletion contrib/gn_module_validation/frontend/app/gnModule.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import { ValidationService } from './services/validation.service';
// my module routing
const routes: Routes = [
{ path: '', component: ValidationComponent },
{ path: 'occurrence/:id_synthese', component: ValidationComponent, pathMatch: 'full' },
{ path: 'occurrence/:id_synthese', component: ValidationComponent },
{ path: 'occurrence/:id_synthese/:tab', component: ValidationComponent },
];

@NgModule({
Expand Down
Loading

0 comments on commit 2acf4c4

Please sign in to comment.