Skip to content

Commit

Permalink
Feat/conditional edit and delete entrance protocol (#89)
Browse files Browse the repository at this point in the history
* feat: conditional delete site

- Delete icon is not showing if visit > 0

Reviewed-by: andriacap

* feat: edit table object (from protocol)

Edit icon in data-table component.
Allow user to directly edit from a datatable component

Reviewed-by: andriacap

* feat: delete visit from protocol and site

Change relationship for module on t_visit_complements model (fix error dependency rules blank)
Change visit-component in order to allow delete when enter through site
Add hide-spinner class to improve UX for delete modal (enter through
site)

Reviewed-by: andriacap
  • Loading branch information
andriacap committed Sep 7, 2023
1 parent fe33b26 commit de2156f
Show file tree
Hide file tree
Showing 13 changed files with 173 additions and 18 deletions.
2 changes: 1 addition & 1 deletion backend/gn_module_monitoring/monitoring/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ class TMonitoringVisits(TBaseVisits, GenericModel):
TModules,
lazy="select",
primaryjoin=(TModules.id_module == TBaseVisits.id_module),
foreign_keys=[TModules.id_module],
foreign_keys=[TBaseVisits.id_module],
uselist=False,
)

Expand Down
3 changes: 2 additions & 1 deletion frontend/app/class/monitoring-object-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,10 @@ export class MonitoringObjectBase {
);
}

navigateToDetail(id = null) {
navigateToDetail(id = null, toEdit = false) {
this._objService.navigate('object', this.moduleCode, this.objectType, id || this.id, {
parents_path: this.parentsPath,
edit: toEdit,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,7 @@
.btn-float-right {
margin: 5px 0;
}

.hide-spinner {
display: none;
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ <h2>Attention</h2>
<i class="fa fa-edit" aria-hidden="true"></i>
</a>

<ng-container *ngIf="!dataTableArray[i].deleteObjLabel.includes('visite')">
<ng-container
*ngIf="dataTableArray[i].objectType == 'visit' ? true : row['nb_visits'] == 0"
>
<a
class="nav-link link cell-link"
(click)="alertMessage(row)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ export class MonitoringDatatableGComponent implements OnInit {
}

onDelete(row) {
this.bDeleteSpinner = true;
row['id'] = row[row.pk];
this._commonService.regularToaster('info', this.msgToaster('Suppression'));
this.onDeleteEvent.emit({ rowSelected: row, objectType: this.activetabType });
Expand All @@ -342,7 +343,6 @@ export class MonitoringDatatableGComponent implements OnInit {

this.rowSelected['name_object'] = row[varNameObjet];
this.bDeleteModal = true;
this.bDeleteSpinner = true;
}

// TODO: Comprendre le fonctionnement de ObjectStatuts et RowsStatus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
display: inline;
transition: background-color 0.5s;
border-radius: 5px;
padding: 0.5rem;
}

.header-filter-span > input {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
<pnx-modal-msg [bDisplayModal]="bDeleteModal" *ngIf="rowSelected">
<h2>Attention</h2>
<p>
Vous êtes sur le point de supprimer
{{ this.child0.template['label_art_def'] }}
<b>{{ this.child0.template['description'] }}</b>
</p>
<button class="btn btn-danger float-right" (click)="onDelete(rowSelected)">
<span
[ngClass]="{ 'hide-spinner': !bDeleteSpinner }"
class="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
></span>
Confirmer la suppression
</button>
<button class="btn btn-primary" (click)="bDeleteModal = false">Annuler</button>
</pnx-modal-msg>
<div *ngIf="child0 && row_save">
<!-- <input
type="text"
Expand Down Expand Up @@ -43,6 +61,23 @@
>
<i class="fa fa-plus" aria-hidden="true"></i>
</a>
<!-- TODO: rajouter les permission currentUser *ngIf="currentUser?.moduleCruved[child0.objectType].U >= child0.config.cruved('U')" -->
<a
class="nav-link link cell-link"
(click)="child0.navigateToDetail(row.id, true)"
matTooltip="Eiter {{ child0.template.label_art_def }}"
>
<i class="fa fa-edit" aria-hidden="true"></i>
</a>
<ng-container *ngIf="child0.objectType == 'visit' ? true : row['nb_visits'] == 0">
<a
class="nav-link link cell-link"
(click)="alertMessage(row)"
matTooltip="Supprimer {{ child0.template.label_art_def }}"
>
<i class="fa fa-trash" aria-hidden="true"></i>
</a>
</ng-container>
</ng-template>
</ngx-datatable-column>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ 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 { CommonService } from '@geonature_common/service/common.service';
import { ObjectService } from '../../services/object.service';

@Component({
selector: 'pnx-monitoring-datatable',
Expand Down Expand Up @@ -48,7 +50,15 @@ export class MonitoringDatatableComponent implements OnInit {
@ViewChild('actionsTemplate') actionsTemplate: TemplateRef<any>;
@ViewChild('hdrTpl') hdrTpl: TemplateRef<any>;

constructor(private _monitoring: MonitoringObjectService) {}
rowSelected;
bDeleteModal: boolean = false;
bDeleteSpinner: boolean = false;

constructor(
private _monitoring: MonitoringObjectService,
private _commonService: CommonService,
private _objectService: ObjectService
) {}

ngOnInit() {
this.initDatatable();
Expand Down Expand Up @@ -234,4 +244,23 @@ export class MonitoringDatatableComponent implements OnInit {
return out;
};
}

msgToaster(action) {
// return `${action} ${this.obj.labelDu()} ${this.obj.description()} effectuée`.trim();
return `${action} effectuée`.trim();
}

onDelete(row) {
this._commonService.regularToaster('info', this.msgToaster('Suppression'));
this._objectService.changeDisplayingDeleteModal(this.bDeleteModal);
this._objectService.changeSelectRow({ rowSelected: row, objectType: this.child0.objectType });
this._objectService.currentDeleteModal.subscribe(
(deletedModal) => (this.bDeleteModal = deletedModal)
);
}

alertMessage(row) {
this.rowSelected = row;
this.bDeleteModal = true;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { Observable, of, forkJoin } from 'rxjs';
import { mergeMap, concatMap } from 'rxjs/operators';
import {
mergeMap,
concatMap,
map,
tap,
take,
takeUntil,
distinctUntilChanged,
catchError,
skipWhile,
} from 'rxjs/operators';

import { MonitoringObject } from '../../class/monitoring-object';
import { Component, OnInit } from '@angular/core';
Expand All @@ -13,6 +23,7 @@ import { DataUtilsService } from '../../services/data-utils.service';
import { AuthService, User } from '@geonature/components/auth/auth.service';
import { CommonService } from '@geonature_common/service/common.service';
import { MapService } from '@geonature_common/map/map.service';
import { ObjectService } from '../../services/object.service';

import { Utils } from '../../utils/utils';
@Component({
Expand Down Expand Up @@ -41,6 +52,7 @@ export class MonitoringObjectComponent implements OnInit {
heightMap;

moduleSet = false;
bDeleteModal = false;

constructor(
private _route: ActivatedRoute,
Expand All @@ -50,7 +62,8 @@ export class MonitoringObjectComponent implements OnInit {
private _formBuilder: FormBuilder,
public mapservice: MapService,
private _auth: AuthService,
private _commonService: CommonService
private _commonService: CommonService,
private _evtObjService: ObjectService
) {}

ngAfterViewInit() {
Expand Down Expand Up @@ -91,7 +104,7 @@ export class MonitoringObjectComponent implements OnInit {
.subscribe(() => {
this.obj.initTemplate(); // pour le html

this.bEdit = this.checkEditParam ? true : false;
this.bEdit = this.checkEditParam == true ? true : false;
// si on est sur une création (pas d'id et id_parent ou pas de module_code pour module (root))
this.bEdit =
this.bEdit ||
Expand All @@ -105,6 +118,8 @@ export class MonitoringObjectComponent implements OnInit {
} else {
this.initObjectsStatus();
}

this.evenListnerTable();
});
}

Expand Down Expand Up @@ -231,7 +246,11 @@ export class MonitoringObjectComponent implements OnInit {
);
this.objForm = this._formBuilder.group({});

this.checkEditParam = params.get('edit') ? true : false;
if (params.get('edit')) {
this.checkEditParam = Boolean(params.get('edit'));
} else {
this.checkEditParam = false;
}
// query param snapshot

// this.obj.parentId = params.get('parentId') && parseInt(params.get('parentId'));
Expand Down Expand Up @@ -281,4 +300,40 @@ export class MonitoringObjectComponent implements OnInit {
}
this.getModuleSet();
}

onDeleteFromTable(event) {
return this._objService
.dataMonitoringObjectService()
.deleteObject(this.obj.moduleCode, event.objectType, event.rowSelected.id);
}

evenListnerTable() {
const $displayModal = this._evtObjService.currentDeleteModal;
const $rowSelected = this._evtObjService.currentRowSelected;

$displayModal
.pipe(
distinctUntilChanged((prev, curr) => prev === curr),
tap((displayModal) => {
this.bDeleteModal = displayModal;
}),
concatMap(() => {
return $rowSelected;
}),
concatMap((rowSelected) => {
return this.onDeleteFromTable(rowSelected).pipe(
distinctUntilChanged((prev, curr) => prev.rowSelected === curr.rowSelected)
);
}),
catchError((err) => {
console.log(err);
this._evtObjService.changeDisplayingDeleteModal(false);
return of(null);
})
)
.subscribe((deletedObj) => {
this.initSites();
this._evtObjService.changeDisplayingDeleteModal(false);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
[obj]="visits"
(onDetailsRow)="seeDetails($event)"
(onEditEvent)="editChild($event)"
(onDeleteEvent)="onDelete($event)"
[bDeleteModalEmitter]="bDeleteModalEmitter"
>
<option-list-btn
add-button
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, EventEmitter } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable, ReplaySubject, forkJoin, iif, of } from 'rxjs';
Expand All @@ -20,6 +20,7 @@ import { breadCrumbElementBase } from '../breadcrumbs/breadcrumbs.component';
import { ConfigJsonService } from '../../services/config-json.service';
import { breadCrumbBase } from '../../class/breadCrumb';
import { setPopup } from '../../functions/popup';
import { DataMonitoringObjectService } from '../../services/data-monitoring-object.service';

@Component({
selector: 'monitoring-visits',
Expand Down Expand Up @@ -60,6 +61,8 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement
checkEditParam: boolean;

modulSelected;
bDeleteModalEmitter = new EventEmitter<boolean>();

private destroyed$: ReplaySubject<boolean> = new ReplaySubject(1);

constructor(
Expand All @@ -73,7 +76,8 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement
private _formService: FormService,
private _configService: ConfigService,
public siteService: SitesService,
protected _configJsonService: ConfigJsonService
protected _configJsonService: ConfigJsonService,
private _objServiceMonitoring: DataMonitoringObjectService
) {
super();
this.getAllItemsCallback = this.getVisits;
Expand Down Expand Up @@ -271,13 +275,14 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement
}

// TODO: voir s'il faut pouvoir supprimer les visites depuis l'entrée par sites
// onDelete($event){
// this._objServiceMonitoring
// .deleteObject($event.rowSelected.module.module_code,$event.objectType, $event.rowSelected.id).subscribe(del =>{
// this.bDeleteModalEmitter.emit(false);
// this.initSiteVisit()
// });
// }
onDelete($event) {
this._objServiceMonitoring
.deleteObject($event.rowSelected.module.module_code, $event.objectType, $event.rowSelected.id)
.subscribe((del) => {
this.bDeleteModalEmitter.emit(false);
this.initSiteVisit();
});
}

partialfuncToFilt(
pageNumber: number,
Expand Down
7 changes: 7 additions & 0 deletions frontend/app/services/monitoring-object.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,20 @@ export class MonitoringObjectService {
}

navigate(routeType, moduleCode, objectType, id, queryParams = {}) {
let editParams = '';
if ('edit' in queryParams && queryParams.edit == true) {
editParams = 'true';
delete queryParams.edit;
}

this._router.navigate(
[
this._configService.frontendModuleMonitoringUrl(),
routeType,
moduleCode,
objectType,
id,
{ edit: editParams },
].filter((s) => !!s),
{
queryParams,
Expand Down
14 changes: 14 additions & 0 deletions frontend/app/services/object.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ export class ObjectService {
private dataListOption = new ReplaySubject<SelectObject[]>(1);
currentListOption = this.dataListOption.asObservable();

private rowSelected = new ReplaySubject<Object>(1);
currentRowSelected = this.rowSelected.asObservable();

private deleteModal = new ReplaySubject<boolean>(1);
currentDeleteModal = this.deleteModal.asObservable();

constructor() {
let storedObjectType = localStorage.getItem('storedObjectType');
let storedObjectTypeParent = localStorage.getItem('storedObjectTypeParent');
Expand Down Expand Up @@ -79,4 +85,12 @@ export class ObjectService {
changeListOption(newListOption: SelectObject[]) {
this.dataListOption.next(newListOption);
}

changeSelectRow(rowSelected) {
this.rowSelected.next(rowSelected);
}

changeDisplayingDeleteModal(isModal: boolean) {
this.deleteModal.next(isModal);
}
}

0 comments on commit de2156f

Please sign in to comment.