Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions backend/geonature/utils/config_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,32 @@ def post_load(self, data, **kwargs):
return data


class ListLastObsColumnConfig(Schema):
prop = fields.String(required=True)
name = fields.String(required=True)


class ListLastObsFiltersConfig(Schema):
TAXONOMY_GROUP2_INPN = fields.Boolean(load_default=True)
TAXONOMY_GROUP3_INPN = fields.Boolean(load_default=True)


class ListLastObsConfig(Schema):

COLUMNS = fields.List(
fields.Nested(ListLastObsColumnConfig),
load_default=[
{"prop": "nom_vern_or_lb_nom", "name": "Taxon"},
{"prop": "date_min", "name": "Date"},
{"prop": "observers", "name": "Observateur"},
],
)
FILTERS = fields.Nested(
ListLastObsFiltersConfig,
load_default=ListLastObsFiltersConfig().load({}),
)


class GnPySchemaConf(Schema):
SQLALCHEMY_DATABASE_URI = fields.String(
required=True,
Expand Down Expand Up @@ -281,6 +307,11 @@ class GnFrontEndConf(Schema):
DISPLAY_STAT_BLOC = fields.Boolean(load_default=True)
STAT_BLOC_TTL = fields.Integer(load_default=3600)
DISPLAY_MAP_LAST_OBS = fields.Boolean(load_default=True)
DISPLAY_LIST_LAST_OBS = fields.Boolean(load_default=False)
LIST_LAST_OBS_CONFIG = fields.Nested(
ListLastObsConfig,
load_default=ListLastObsConfig().load({}),
)
MULTILINGUAL = fields.Boolean(load_default=False)
ENABLE_PROFILES = fields.Boolean(load_default=True)

Expand Down
16 changes: 16 additions & 0 deletions config/default_config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ MEDIA_CLEAN_CRONTAB = "0 1 * * *"

# Affiche la carte des 100 dernieres observations sur la page d'accueil
DISPLAY_MAP_LAST_OBS = true
# Affiche la liste des 100 dernieres observations sur la page d'accueil
# Si DISPLAY_MAP_LAST_OBS = true, la carte reste prioritaire sur la liste
DISPLAY_LIST_LAST_OBS = false

# Affiche le selecteur de langue dans l'interface
MULTILINGUAL = false
Expand All @@ -146,6 +149,19 @@ MEDIA_CLEAN_CRONTAB = "0 1 * * *"
# Activer l'affichage des informations liées aux profils de taxons (dans les modules Validation, Synthèse et Occtax)
ENABLE_PROFILES = true

[FRONTEND.LIST_LAST_OBS_CONFIG]
# Colonnes affichées dans la liste des dernières observations
# Les colonnes doivent exister dans SYNTHESE.LIST_COLUMNS_FRONTEND
# ou SYNTHESE.ADDITIONAL_COLUMNS_FRONTEND, sinon elles ne pourront pas être prises en compte.
COLUMNS = [
{ prop = "nom_vern_or_lb_nom", name = "Taxon" },
{ prop = "date_min", name = "Date" },
{ prop = "observers", name = "Observateur" },
]

[FRONTEND.LIST_LAST_OBS_CONFIG.FILTERS]
TAXONOMY_GROUP2_INPN = true
TAXONOMY_GROUP3_INPN = true
# Afficher l'organisme de l'utilisateur dans la barre de navigation (true / false)
DISPLAY_USER_ORGANISM = true

Expand Down
3 changes: 2 additions & 1 deletion frontend/cypress/fixtures/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@
"DISPLAY_EMAIL_INFO_OBS": true,
"DISPLAY_STAT_BLOC": true,
"PROD_MOD": true,
"DISPLAY_MAP_LAST_OBS": true
"DISPLAY_MAP_LAST_OBS": true,
"DISPLAY_LIST_LAST_OBS": false
},
"DEFAULT_LANGUAGE": "fr",
"ACCOUNT_MANAGEMENT": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
<div
*ngIf="isLoading; else content"
class="SpinnerContainer"
>
<mat-spinner></mat-spinner>
<p *ngIf="message">{{ message }}</p>
</div>
<ng-template #content>
<ng-content />
<ng-container *ngIf="mode === LoadableLayoutMode.Replace; else overlayMode">
<div
*ngIf="isLoading; else replaceContent"
class="SpinnerContainer"
>
<mat-spinner></mat-spinner>
<p *ngIf="message">{{ message }}</p>
</div>
<ng-template #replaceContent>
<ng-content></ng-content>
</ng-template>
</ng-container>

<ng-template #overlayMode>
<div class="LoadableLayout">
<div class="LoadableLayout__content">
<ng-content></ng-content>
</div>

<div
*ngIf="isLoading"
class="SpinnerContainer SpinnerContainer--overlay"
>
<mat-spinner></mat-spinner>
<p *ngIf="message">{{ message }}</p>
</div>
</div>
</ng-template>
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
.LoadableLayout {
position: relative;
display: flex;
width: 100%;
height: 100%;
min-height: 0;

&__content {
display: flex;
flex: 1 1 auto;
min-height: 0;
}
}

.SpinnerContainer {
// max-height: 100%;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
z-index: 10; /* Ensure the spinner is above other content */
flex-direction: column;

&--overlay {
position: absolute;
inset: 0;
z-index: 10;
background: rgba(255, 255, 255, 0.65);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import { Component, Input } from '@angular/core';

export enum LoadableLayoutMode {
Overlay = 'overlay',
Replace = 'replace',
}

@Component({
selector: 'gn-loadable-layout',
templateUrl: 'loadable-layout.component.html',
styleUrls: ['loadable-layout.component.scss'],
})
export class LoadableLayoutComponent {
readonly LoadableLayoutMode = LoadableLayoutMode;

@Input()
isLoading: boolean = false;
@Input()
message: string = null;
@Input()
mode: LoadableLayoutMode = LoadableLayoutMode.Overlay;
}
20 changes: 15 additions & 5 deletions frontend/src/app/GN2CommonModule/map/geojson/geojson.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,22 @@ export class GeojsonComponent implements OnInit, OnChanges {
}
}
if (changes.style && changes.style.currentValue !== undefined) {
if (this.currentGeojson) {
for (const key of Object.keys(this.currentGeojson['_layers'])) {
const layer = this.currentGeojson['_layers'][key];
layer.setStyle(changes.style.currentValue);
}
this.applyStyle(changes.style.currentValue);
}
}

private applyStyle(style) {
if (!this.currentGeojson || !this.currentGeojson['_layers']) {
return;
}

for (const key of Object.keys(this.currentGeojson['_layers'])) {
const layer = this.currentGeojson['_layers'][key];
if (!layer.setStyle) {
continue;
}

layer.setStyle(style);
}
}
}
3 changes: 1 addition & 2 deletions frontend/src/app/GN2CommonModule/map/map.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,14 @@ export class MapService {
const geojsonLayer = L.geoJSON(geojson?.features || geojson, {
style: (feature) => {
switch (feature.geometry.type) {
// No color nor opacity for linestrings
case 'LineString':
return style || this.lineStyle();
default:
return style || this.defaultStyle();
}
},
pointToLayer: (feature, latlng) => {
return L.circleMarker(latlng);
return L.circleMarker(latlng, style || this.defaultStyle());
},
onEachFeature: onEachFeature,
});
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { GN2CommonModule } from '@geonature_common/GN2Common.module';
import { AppComponent } from './app.component';
import { routing } from './routing/app-routing.module'; // RoutingModule
import { HomeContentComponent } from './components/home-content/home-content.component';
import { HomeContentListObsComponent } from './components/home-content/home-content-list-obs/home-content-list-obs.component';
import { HomeDiscussionsComponent } from './components/home-content/home-discussions/home-discussions.component';
import { HomeValidationsComponent } from './components/home-content/home-validations/home-validations.component';

Expand Down Expand Up @@ -107,6 +108,7 @@ export function initApp(injector) {
extend: true,
}),
LoginModule,
HomeContentListObsComponent,
HomeDiscussionsComponent,
HomeValidationsComponent,
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<div class="home-content-list-obs-filters">
<ng-select
*ngIf="showGroup2Filter"
[items]="group2InpnOptions"
[formControl]="group2InpnControl"
bindLabel="value"
bindValue="value"
[clearable]="true"
[searchable]="true"
placeholder="Groupe 2 INPN"
></ng-select>

<ng-select
*ngIf="showGroup3Filter"
[items]="group3InpnOptions"
[formControl]="group3InpnControl"
bindLabel="value"
bindValue="value"
[clearable]="true"
[searchable]="true"
placeholder="Groupe 3 INPN"
></ng-select>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
.home-content-list-obs-filters {
display: flex;
flex-flow: row nowrap;
gap: 0.5rem;
align-items: center;

ng-select {
width: 200px !important;
font-size: 0.875rem;
}

::ng-deep ng-select .ng-select-container {
min-height: 34px;
padding: 0 0.35rem;
}

::ng-deep ng-select .ng-value-container {
padding-left: 0.1rem;
}

::ng-deep ng-select .ng-input {
top: 6px;
padding-left: 0.1rem;
}

::ng-deep ng-select .ng-placeholder,
::ng-deep ng-select .ng-value-label,
::ng-deep ng-select .ng-input input {
font-size: 0.875rem;
line-height: 1.2;
}

::ng-deep ng-select .ng-clear-wrapper,
::ng-deep ng-select .ng-arrow-wrapper {
padding-left: 0.3rem;
padding-right: 0.1rem;
}

::ng-deep ng-dropdown-panel .ng-dropdown-panel-items .ng-option {
white-space: nowrap;
}

::ng-deep ng-dropdown-panel .ng-dropdown-panel-items .ng-option span {
white-space: nowrap;
overflow: visible;
text-overflow: clip;
}
}
Loading
Loading