From b2c7d55bd369e248f3103614a35c6a73cf5baae4 Mon Sep 17 00:00:00 2001 From: Maxime Vergez <85738261+mvergez@users.noreply.github.com> Date: Fri, 14 Apr 2023 16:02:57 +0200 Subject: [PATCH] Feat/prepare edit site component & some visits (#43) * refactor: object.service with observable obj Change the objectType string to objectType obj in order to subscribe to multilple properties link to this object Reviewed-by: andriacap [Refs_ticket]: #40 * feat: adapt service to get config json Get fieldsName and fieldsLabel for display properties (properties component) Add logic to setItem in LocalStorage to keepLast Value of observable on reload page TODO: - [ ] see if Localstorage is really necessary with the configService used inside api-geom.service ) - [ ] adapt monitoring-form-g.component with the new service Reviewed-by: andriacap [Refs ticket]: #4 * feat: column datatable from config json Add logic into sitegroups service in order to use config json to diplay column datatable (called "display_list") Review-by: andriac [Refs ticket]: #4 * feat: adjust backend to load config json Adjust backend code to use existing code in order to load config from file json and by starting with "sites_group" Fix Media load and upload for site_group TODO: - [ ] check if config should be find from file or backend - [ ] Optimize logic backend (use generic model with class method ?) Reviewed-by: andriacap [Refs ticket]: #4 * feat: add button multiselect with filter on backend filter with params backend (new route -> see if it's possible to change that) Add button multiselect above form type site TODO: - improve Input / condition of use case of btn multiselect Reviewed-by: andriac * feat: btn multiselect option -Add @Input fn , placeholder, title, paramsToFilt -Remove empty option -prevent adding from keyboard input or not including in list -Store config json into object Reviewed-by: @andriac [Refs-ticket]: #4 * refactor: change form-service and object-service refactor form-service add observable into object-service (WIP: futur use for refresh page ?) Rieviewed-by: andriac [Refs_ticket]: #40 * refactor: test refresh page and comportment obs refresh page seems to works with localstorage of different obj in object_service Reviewed-by: andriac * feat: dynamic form - Add: - pass config json to form.component-g.ts - add config json to this.obj and refresh form into form.component-g.ts - add css for form component to deal when long form selected -fix : - refresh page form component (this._configService.init is necessary ...) - comportment different between add or edit into form component and form service Reviewed-by: andriac [Refs_ticket]: #4 * feat: dynamic form - Correction PR Remove unused console.log Rxjs : use concatMap to avoid subscribe inside subscribe Apply: prettier and sort prettier for import ts file Reviewed-by: @andriac [Refs_PR]: #42 * feat: dynamic create site - Add change current-object when click "Add " from datatable component - api-geom.service: change the way to init the api-geom - WIP: two subscribes in one .. (the subscription is call only once ..) - WIP : get config json from backend Reviewed-by: andriac * feat: add relationship id into sendData form site Add type_site and id_site_group to the form site Reviewed-by: andriac [Refs_ticket]: #5 et #6 * feat(back): add custom config when post site Change backend files in order to choose specific config when site is created. Reviewed-by: andriac [Refs_ticket]: #5 , #6 * fix: problem of type object when loading form Add endPoint and objectType to the observable using by the formservice in order to use _apiGeomService with good context (endPoint) [Refs_ticket]: #5 et #6 * fix: tooltip and label inside datatable-component Add a childLabel inside interface objObs.ts in order to use this tooltip inside datatable-component * feat: get back work visitcomponent get back work from feat/visit to use visitcomponent but adapted to current branch [Refs_ticket]: #5 , #6 * fix: forgot 3 modifications needed from feat/site Add conftest visit Add test_get_visits Add get_site_by_id * fix: passing data between components and property - Action button "consult..." is working for group_site and site - Action with button "cancel" , "come back history routing" send to the right component - Label and tooltip are according to the parent and child object loaded in the corresponding component - Action "Add site" directly from datatable-g.component (WIP: need to remove send to sites_group/:id/create [Refs_ticket]: #40 , #4 , #5 and #6 * fix: error of url relative when using form Fix problem of id_module has ["id_module"] in create_or_update_object_api function Fix path "sites/:id" to "site/:id" Add urlRelative when editing component * fix: problem route navigation Remove unused "urlRelative" create in last commit Fix the action "add children" in datatable to redirect to the good component Change the way to redirect when cancel and delete on form component based on last url [Refs_ticket]: #40 * refactor: object.service with observable obj Change the objectType string to objectType obj in order to subscribe to multilple properties link to this object Reviewed-by: andriacap [Refs_ticket]: #40 * feat: adapt service to get config json Get fieldsName and fieldsLabel for display properties (properties component) Add logic to setItem in LocalStorage to keepLast Value of observable on reload page TODO: - [ ] see if Localstorage is really necessary with the configService used inside api-geom.service ) - [ ] adapt monitoring-form-g.component with the new service Reviewed-by: andriacap [Refs ticket]: #4 * feat: column datatable from config json Add logic into sitegroups service in order to use config json to diplay column datatable (called "display_list") Review-by: andriac [Refs ticket]: #4 * feat: adjust backend to load config json Adjust backend code to use existing code in order to load config from file json and by starting with "sites_group" Fix Media load and upload for site_group TODO: - [ ] check if config should be find from file or backend - [ ] Optimize logic backend (use generic model with class method ?) Reviewed-by: andriacap [Refs ticket]: #4 * feat: add button multiselect with filter on backend filter with params backend (new route -> see if it's possible to change that) Add button multiselect above form type site TODO: - improve Input / condition of use case of btn multiselect Reviewed-by: andriac * feat: btn multiselect option -Add @Input fn , placeholder, title, paramsToFilt -Remove empty option -prevent adding from keyboard input or not including in list -Store config json into object Reviewed-by: @andriac [Refs-ticket]: #4 * refactor: change form-service and object-service refactor form-service add observable into object-service (WIP: futur use for refresh page ?) Rieviewed-by: andriac [Refs_ticket]: #40 * refactor: test refresh page and comportment obs refresh page seems to works with localstorage of different obj in object_service Reviewed-by: andriac * feat: dynamic form - Add: - pass config json to form.component-g.ts - add config json to this.obj and refresh form into form.component-g.ts - add css for form component to deal when long form selected -fix : - refresh page form component (this._configService.init is necessary ...) - comportment different between add or edit into form component and form service Reviewed-by: andriac [Refs_ticket]: #4 * feat: dynamic form - Correction PR Remove unused console.log Rxjs : use concatMap to avoid subscribe inside subscribe Apply: prettier and sort prettier for import ts file Reviewed-by: @andriac [Refs_PR]: #42 * feat: dynamic create site - Add change current-object when click "Add " from datatable component - api-geom.service: change the way to init the api-geom - WIP: two subscribes in one .. (the subscription is call only once ..) - WIP : get config json from backend Reviewed-by: andriac * feat: add relationship id into sendData form site Add type_site and id_site_group to the form site Reviewed-by: andriac [Refs_ticket]: #5 et #6 * feat(back): add custom config when post site Change backend files in order to choose specific config when site is created. Reviewed-by: andriac [Refs_ticket]: #5 , #6 * fix: tooltip and label inside datatable-component Add a childLabel inside interface objObs.ts in order to use this tooltip inside datatable-component * feat: get back work visitcomponent get back work from feat/visit to use visitcomponent but adapted to current branch [Refs_ticket]: #5 , #6 * fix: forgot 3 modifications needed from feat/site Add conftest visit Add test_get_visits Add get_site_by_id * fix: passing data between components and property - Action button "consult..." is working for group_site and site - Action with button "cancel" , "come back history routing" send to the right component - Label and tooltip are according to the parent and child object loaded in the corresponding component - Action "Add site" directly from datatable-g.component (WIP: need to remove send to sites_group/:id/create [Refs_ticket]: #40 , #4 , #5 and #6 * fix: error of url relative when using form Fix problem of id_module has ["id_module"] in create_or_update_object_api function Fix path "sites/:id" to "site/:id" Add urlRelative when editing component * fix: fix things broken by rebase * chore: remove useless file * chore(front): remove file/comment/console.log --------- Co-authored-by: Andria Capai --- .../config/generic/site.json | 11 +-- .../gn_module_monitoring/monitoring/models.py | 20 +++- .../monitoring/schemas.py | 17 +++- backend/gn_module_monitoring/routes/site.py | 6 ++ .../routes/sites_groups.py | 44 +++++++++ backend/gn_module_monitoring/routes/visit.py | 35 +++++++ .../gn_module_monitoring/tests/conftest.py | 1 + .../tests/fixtures/visit.py | 27 ++++++ .../tests/test_routes/test_visit.py | 29 ++++++ frontend/app/class/monitoring-visit.ts | 6 ++ .../monitoring-datatable-g.component.html | 6 +- .../monitoring-datatable-g.component.ts | 18 +++- .../monitoring-form.component-g.ts | 33 ++++--- .../monitoring-properties-g.component.ts | 64 +++++++------ .../monitoring-sites-create.component.ts | 43 ++++++--- .../monitoring-sites-edit.component.css | 0 .../monitoring-sites-edit.component.html | 13 +++ .../monitoring-sites-edit.component.ts | 73 +++++++++++++++ .../monitoring-sites.component.html | 1 + .../monitoring-sites.component.ts | 36 ++++---- ...monitoring-sitesgroups-create.component.ts | 40 +++++--- .../monitoring-sitesgroups.component.ts | 1 - .../monitoring-visits.component.css | 0 .../monitoring-visits.component.html | 8 ++ .../monitoring-visits.component.ts | 92 +++++++++++++++++++ frontend/app/enum/endpoints.ts | 1 + frontend/app/gnModule.module.ts | 19 +++- frontend/app/interfaces/geom.ts | 6 ++ frontend/app/interfaces/objObs.ts | 7 +- frontend/app/interfaces/object.ts | 20 ++++ frontend/app/interfaces/visit.ts | 18 ++++ frontend/app/services/api-geom.service.ts | 77 +++++++++++++++- frontend/app/services/config-json.service.ts | 1 + frontend/app/services/form.service.ts | 14 ++- 34 files changed, 660 insertions(+), 127 deletions(-) create mode 100644 backend/gn_module_monitoring/routes/visit.py create mode 100644 backend/gn_module_monitoring/tests/fixtures/visit.py create mode 100644 backend/gn_module_monitoring/tests/test_routes/test_visit.py create mode 100644 frontend/app/class/monitoring-visit.ts create mode 100644 frontend/app/components/monitoring-sites-edit/monitoring-sites-edit.component.css create mode 100644 frontend/app/components/monitoring-sites-edit/monitoring-sites-edit.component.html create mode 100644 frontend/app/components/monitoring-sites-edit/monitoring-sites-edit.component.ts create mode 100644 frontend/app/components/monitoring-visits/monitoring-visits.component.css create mode 100644 frontend/app/components/monitoring-visits/monitoring-visits.component.html create mode 100644 frontend/app/components/monitoring-visits/monitoring-visits.component.ts create mode 100644 frontend/app/interfaces/object.ts create mode 100644 frontend/app/interfaces/visit.ts diff --git a/backend/gn_module_monitoring/config/generic/site.json b/backend/gn_module_monitoring/config/generic/site.json index 65fe26895..079d977bb 100644 --- a/backend/gn_module_monitoring/config/generic/site.json +++ b/backend/gn_module_monitoring/config/generic/site.json @@ -59,13 +59,6 @@ "type_util": "user", "required": true }, - "id_digitiser": { - "type_widget": "text", - "attribut_label": "Numérisateur", - "required": true, - "hidden": true, - "type_util": "user" - }, "first_use_date": { "type_widget": "date", "attribut_label": "Date description", @@ -90,11 +83,11 @@ "type_widget": "integer", "attribut_label": "Altitude (min)" }, - "altitude_max": { + "altitude_max": { "type_widget": "integer", "attribut_label": "Altitude (max)" }, - "id_sites_group": { + "id_sites_group": { "type_widget": "integer", "attribut_label": "ID Sites Groups", "hidden": true, diff --git a/backend/gn_module_monitoring/monitoring/models.py b/backend/gn_module_monitoring/monitoring/models.py index 9ea917069..a4f3493c1 100644 --- a/backend/gn_module_monitoring/monitoring/models.py +++ b/backend/gn_module_monitoring/monitoring/models.py @@ -171,13 +171,13 @@ class TMonitoringObservations(TObservations): @serializable -class TMonitoringVisits(TBaseVisits): +class TMonitoringVisits(TBaseVisits, GenericModel): __tablename__ = "t_visit_complements" __table_args__ = {"schema": "gn_monitoring"} __mapper_args__ = { "polymorphic_identity": "monitoring_visit", } - + query_class = MonitoringQuery id_base_visit = DB.Column( DB.ForeignKey("gn_monitoring.t_base_visits.id_base_visit"), nullable=False, @@ -210,10 +210,20 @@ class TMonitoringVisits(TBaseVisits): ) + module = DB.relationship( + TModules, + lazy="select", + primaryjoin=(TModules.id_module == TBaseVisits.id_module), + foreign_keys=[TModules.id_module], + uselist=False, + ) + + @geoserializable(geoCol="geom", idCol="id_base_site") -class TMonitoringSites(TBaseSites): - __tablename__ = "t_site_complements" - __table_args__ = {"schema": "gn_monitoring"} +class TMonitoringSites(TBaseSites, GenericModel): + + __tablename__ = 't_site_complements' + __table_args__ = {'schema': 'gn_monitoring'} __mapper_args__ = { "polymorphic_identity": "monitoring_site", } diff --git a/backend/gn_module_monitoring/monitoring/schemas.py b/backend/gn_module_monitoring/monitoring/schemas.py index fcbbc76d3..7dde989c3 100644 --- a/backend/gn_module_monitoring/monitoring/schemas.py +++ b/backend/gn_module_monitoring/monitoring/schemas.py @@ -3,12 +3,13 @@ import geojson from geonature.utils.env import MA from marshmallow import Schema, fields, validate -from geonature.core.gn_commons.schemas import MediaSchema +from geonature.core.gn_commons.schemas import MediaSchema, ModuleSchema from gn_module_monitoring.monitoring.models import ( BibTypeSite, TMonitoringSites, TMonitoringSitesGroups, + TMonitoringVisits ) @@ -51,11 +52,14 @@ class Meta: exclude = ("geom_geojson", "geom") geometry = fields.Method("serialize_geojson", dump_only=True) + pk = fields.Method("set_pk",dump_only=True) def serialize_geojson(self, obj): if obj.geom is not None: return geojson.dumps(obj.as_geofeature().get("geometry")) - + + def set_pk(self,obj): + return self.Meta.model.get_id() class BibTypeSiteSchema(MA.SQLAlchemyAutoSchema): label = fields.Method("get_label_from_type_site") @@ -69,3 +73,12 @@ class Meta: model = BibTypeSite include_fk = True load_instance = True + +class MonitoringVisitsSchema(MA.SQLAlchemyAutoSchema): + class Meta: + model = TMonitoringVisits + pk = fields.Method("set_pk",dump_only=True) + module = MA.Nested(ModuleSchema) + + def set_pk(self,obj): + return self.Meta.model.get_id() diff --git a/backend/gn_module_monitoring/routes/site.py b/backend/gn_module_monitoring/routes/site.py index 1bc413785..0e2444b37 100644 --- a/backend/gn_module_monitoring/routes/site.py +++ b/backend/gn_module_monitoring/routes/site.py @@ -6,6 +6,7 @@ from gn_module_monitoring.config.repositories import get_config from gn_module_monitoring.monitoring.models import BibTypeSite, TMonitoringSites, TNomenclatures from gn_module_monitoring.monitoring.schemas import BibTypeSiteSchema, MonitoringSitesSchema +from gn_module_monitoring.routes.sites_groups import create_or_update_object_api from gn_module_monitoring.utils.routes import ( create_or_update_object_api_sites_sites_group, filter_params, @@ -85,6 +86,11 @@ def get_sites(): page=page, ) +@blueprint.route("/sites/", methods=["GET"]) +def get_site_by_id(id_base_site): + site = TMonitoringSites.query.get_or_404(id_base_site) + schema = MonitoringSitesSchema() + return schema.dump(site) @blueprint.route("/sites/geometries", methods=["GET"]) def get_all_site_geometries(): diff --git a/backend/gn_module_monitoring/routes/sites_groups.py b/backend/gn_module_monitoring/routes/sites_groups.py index 28888ef30..1c4ed6832 100644 --- a/backend/gn_module_monitoring/routes/sites_groups.py +++ b/backend/gn_module_monitoring/routes/sites_groups.py @@ -103,3 +103,47 @@ def handle_validation_error(error): status_code=422, payload=error.data, ).to_dict() + + +# TODO: OPTIMIZE in order to adapt to new monitoring module (entry by sites_groups) + + +def create_or_update_object_api(module_code, object_type, id=None): + """ + route pour la création ou la modification d'un objet + si id est renseigné, c'est une création (PATCH) + sinon c'est une modification (POST) + + :param module_code: reference le module concerne + :param object_type: le type d'object (site, visit, obervation) + :param id : l'identifiant de l'object (de id_base_site pour site) + :type module_code: str + :type object_type: str + :type id: int + :return: renvoie l'object crée ou modifié + :rtype: dict + """ + depth = to_int(request.args.get("depth", 1)) + + # recupération des données post + post_data = dict(request.get_json()) + if module_code != "generic": + module = get_module("module_code", module_code) + else: + module = {"id_module": "generic"} + #TODO : A enlever une fois que le post_data contiendra geometry et type depuis le front + if object_type == "site": + post_data["geometry"]={'type':'Point', 'coordinates':[2.5,50]} + post_data["type"]='Feature' + # on rajoute id_module s'il n'est pas renseigné par défaut ?? + if "id_module" not in post_data["properties"]: + module["id_module"] = "generic" + post_data["properties"]["id_module"] = module["id_module"] + else: + post_data["properties"]["id_module"] = module["id_module"] + + return ( + monitoring_g_definitions.monitoring_object_instance(module_code, object_type, id) + .create_or_update(post_data) + .serialize(depth) + ) diff --git a/backend/gn_module_monitoring/routes/visit.py b/backend/gn_module_monitoring/routes/visit.py new file mode 100644 index 000000000..4303ba51e --- /dev/null +++ b/backend/gn_module_monitoring/routes/visit.py @@ -0,0 +1,35 @@ +from flask import request +from sqlalchemy.orm import joinedload +from werkzeug.datastructures import MultiDict + +from gn_module_monitoring.blueprint import blueprint +from gn_module_monitoring.monitoring.models import TMonitoringVisits +from gn_module_monitoring.monitoring.schemas import MonitoringVisitsSchema +from gn_module_monitoring.utils.routes import ( + filter_params, + get_limit_page, + get_sort, + paginate, + sort, +) + +# Retrieves visits that do not depend on modules + + +@blueprint.route("/visits", methods=["GET"]) +def get_visits(): + params = MultiDict(request.args) + limit, page = get_limit_page(params=params) + sort_label, sort_dir = get_sort( + params=params, default_sort="id_base_visit", default_direction="desc" + ) + query = TMonitoringVisits.query.options(joinedload(TMonitoringVisits.module)) + query = filter_params(query=TMonitoringVisits.query, params=params) + query = sort(query=query, sort=sort_label, sort_dir=sort_dir) + + return paginate( + query=query, + schema=MonitoringVisitsSchema, + limit=limit, + page=page, + ) diff --git a/backend/gn_module_monitoring/tests/conftest.py b/backend/gn_module_monitoring/tests/conftest.py index 422312d22..92ab61efc 100644 --- a/backend/gn_module_monitoring/tests/conftest.py +++ b/backend/gn_module_monitoring/tests/conftest.py @@ -6,4 +6,5 @@ "gn_module_monitoring.tests.fixtures.site", "gn_module_monitoring.tests.fixtures.sites_groups", "gn_module_monitoring.tests.fixtures.type_site", + "gn_module_monitoring.tests.fixtures.visit", ] diff --git a/backend/gn_module_monitoring/tests/fixtures/visit.py b/backend/gn_module_monitoring/tests/fixtures/visit.py new file mode 100644 index 000000000..cd7dc197d --- /dev/null +++ b/backend/gn_module_monitoring/tests/fixtures/visit.py @@ -0,0 +1,27 @@ +import datetime + +import pytest +from geonature.tests.fixtures import datasets +from geonature.utils.env import db + +from gn_module_monitoring.monitoring.models import TMonitoringVisits + + +@pytest.fixture +def visits(module, users, types_site, sites, datasets): + now = datetime.datetime.now() + dataset = datasets["orphan_dataset"] + db_visits = [] + for site in sites.values(): + db_visits.append( + TMonitoringVisits( + id_base_site=site.id_base_site, + id_module=module.id_module, + id_dataset=dataset.id_dataset, + visit_date_min=now, + ) + ) + with db.session.begin_nested(): + db.session.add_all(db_visits) + + return db_visits diff --git a/backend/gn_module_monitoring/tests/test_routes/test_visit.py b/backend/gn_module_monitoring/tests/test_routes/test_visit.py new file mode 100644 index 000000000..67de0f658 --- /dev/null +++ b/backend/gn_module_monitoring/tests/test_routes/test_visit.py @@ -0,0 +1,29 @@ +import pytest +from flask import url_for + + +@pytest.mark.usefixtures("client_class", "temporary_transaction") +class TestVisits: + def test_get_visits(self, visits): + r = self.client.get( + url_for( + "monitorings.get_visits", + ) + ) + + expected_visits = {visit.id_base_visit for visit in visits} + current_visits = {visit["id_base_visit"] for visit in r.json["items"]} + assert expected_visits.issubset(current_visits) + assert all(visit["module"] is not None for visit in r.json["items"]) + + def test_get_visits_with_site(self, visits, sites): + site = list(sites.values())[0] + + r = self.client.get(url_for("monitorings.get_visits", id_base_site=site.id_base_site)) + + expected_visits = { + visit.id_base_visit for visit in visits if visit.id_base_site == site.id_base_site + } + current_visits = {visit["id_base_visit"] for visit in r.json["items"]} + + assert expected_visits.issubset(current_visits) diff --git a/frontend/app/class/monitoring-visit.ts b/frontend/app/class/monitoring-visit.ts new file mode 100644 index 000000000..5f34dc629 --- /dev/null +++ b/frontend/app/class/monitoring-visit.ts @@ -0,0 +1,6 @@ +export enum columnNameVisit { + id_module = "Protocol ID", + visit_date_max = "Date max", + visit_date_min = "Date min", + nb_observations = "Nb. observations", +} 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 7db5849a0..095b562a1 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 @@ -52,15 +52,15 @@ 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 73bb836d8..816fe4e6d 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 @@ -186,12 +186,20 @@ export class MonitoringDatatableGComponent implements OnInit { } } } - navigateToAddChildren(_, rowId) { - this.addEvent.emit(rowId); + navigateToAddChildren(_, row) { + this.addEvent.emit(row); this._objService.changeObjectType(this.objectType); - this.router.navigate(['create'], { - relativeTo: this._Activatedroute, - }); + if (row){ + row['id'] = row[row.pk]; + this.router.navigate([row.id,'create'], { + relativeTo: this._Activatedroute, + }); + } else { + this.router.navigate(['create'], { + relativeTo: this._Activatedroute, + }); + } + } navigateToDetail(row) { row['id'] = row.pk; 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 683fbe72f..cf28af17f 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 @@ -60,7 +60,6 @@ export class MonitoringFormComponentG implements OnInit { private _formService: FormService, private _apiGeomService: ApiGeomService, private _router: Router, - private _objService: ObjectService ) {} ngOnInit() { @@ -92,7 +91,6 @@ export class MonitoringFormComponentG implements OnInit { } - // meta pour les parametres dynamiques // ici pour avoir acces aux nomenclatures this.meta = { @@ -261,14 +259,20 @@ export class MonitoringFormComponentG implements OnInit { */ navigateToDetail(id, objectType, queryParams) { // patch bug navigation - this._router.navigate( - ['monitorings', objectType, id].filter((s) => !!s), - { - queryParams, - } - ); + // this._router.navigate( + // ['monitorings', objectType, id].filter((s) => !!s), + // { + // queryParams, + // } + // ); + // TODO: this commented code works only if ".." is not based url (example working : sites_group/:id/site/:id , not working if create site_group) + // this._router.navigate(['..',objectType,id], {relativeTo: this._route}); + // + const urlSegment = [objectType, id].filter((s) => !!s); + const urlPathDetail = [this.obj.urlRelative].concat(urlSegment).join('/'); this.objChanged.emit(this.obj); this.bEditChange.emit(false); + this._router.navigateByUrl(urlPathDetail); } /** @@ -276,11 +280,11 @@ export class MonitoringFormComponentG implements OnInit { */ navigateToParent() { this.bEditChange.emit(false); // patch bug navigation - this._router.navigateByUrl('/monitorings/sites_group'); - - // this.obj.navigateToParent(); + this._router.navigate(['..'], {relativeTo: this._route}); } + + msgToaster(action) { // return `${action} ${this.obj.labelDu()} ${this.obj.description()} effectuée`.trim(); return `${action} effectuée`.trim(); @@ -298,7 +302,10 @@ export class MonitoringFormComponentG implements OnInit { action.subscribe((objData) => { this._commonService.regularToaster('success', this.msgToaster(actionLabel)); this.bSaveSpinner = this.bSaveAndAddChildrenSpinner = false; - // this.objChanged.emit(this.obj); + if (objData.hasOwnProperty('id')) { + this.obj.id = objData['id']; + } + this.objChanged.emit(this.obj); /** si c'est un module : reset de la config */ if (this.obj.objectType === 'module') { @@ -388,6 +395,6 @@ export class MonitoringFormComponentG implements OnInit { } } Object.assign(this.obj.dataComplement, event); - this._formService.dataToCreate(this.obj); + this._formService.dataToCreate(this.obj, this.obj.urlRelative); } } 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 0c4cf5456..3c411bf06 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 @@ -1,55 +1,63 @@ -import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core"; -import { FormControl } from "@angular/forms"; -import { ISitesGroup } from "../../interfaces/geom"; -import { IobjObs, ObjDataType } from "../../interfaces/objObs"; -import { FormService } from "../../services/form.service"; -import { ObjectService } from "../../services/object.service"; -import { JsonData } from "../../types/jsondata"; +import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { Subscription } from 'rxjs'; + +import { ISitesGroup } from '../../interfaces/geom'; +import { IobjObs, ObjDataType } from '../../interfaces/objObs'; +import { FormService } from '../../services/form.service'; +import { ObjectService } from '../../services/object.service'; +import { JsonData } from '../../types/jsondata'; @Component({ - selector: "pnx-monitoring-properties-g", - templateUrl: "./monitoring-properties-g.component.html", - styleUrls: ["./monitoring-properties-g.component.css"], + selector: 'pnx-monitoring-properties-g', + templateUrl: './monitoring-properties-g.component.html', + styleUrls: ['./monitoring-properties-g.component.css'], }) export class MonitoringPropertiesGComponent implements OnInit { // selectedObj: ISitesGroup; @Input() selectedObj: ObjDataType; @Input() bEdit: boolean; @Output() bEditChange = new EventEmitter(); - @Input() objectType: IobjObs; + objectType: IobjObs; - color: string = "white"; + @Input() newParentType; + color: string = 'white'; dataDetails: ISitesGroup; fields: JsonData; fieldDefinitions: JsonData; fieldsNames: string[]; - endPoint:string; + endPoint: string; datasetForm = new FormControl(); + _sub: Subscription; - constructor( - private _formService: FormService, - private _objService: ObjectService, - ) {} + constructor(private _formService: FormService, private _objService: ObjectService) {} ngOnInit() { - this._objService.currentObjectTypeParent.subscribe((newObjType) => { - this.objectType = newObjType; - this.fieldsNames = newObjType.template.fieldNames; - this.fields = newObjType.template.fieldLabels; - this.fieldDefinitions = newObjType.template.fieldDefinitions; - this.objectType.properties = this.selectedObj; - this.endPoint = newObjType.endPoint; - }); + this.initProperties(); + } + + initProperties() { + this.objectType = this.newParentType; + this.fieldsNames = this.newParentType.template.fieldNames; + this.fields = this.newParentType.template.fieldLabels; + this.fieldDefinitions = this.newParentType.template.fieldDefinitions; + this.objectType.properties = this.selectedObj; + this.endPoint = this.newParentType.endPoint; } onEditClick() { this.bEditChange.emit(true); - this.selectedObj["id"] = this.selectedObj[this.selectedObj.pk]; + this.selectedObj['id'] = this.selectedObj[this.selectedObj.pk]; this._formService.changeDataSub( this.selectedObj, this.objectType.objectType, - this.objectType.endPoint, - this.objectType + this.objectType.endPoint ); } + + ngOnChanges(changes: SimpleChanges): void { + if (this.newParentType.template.fieldNames.length != 0) { + this.initProperties(); + } + } } diff --git a/frontend/app/components/monitoring-sites-create/monitoring-sites-create.component.ts b/frontend/app/components/monitoring-sites-create/monitoring-sites-create.component.ts index 32514d56f..33741d789 100644 --- a/frontend/app/components/monitoring-sites-create/monitoring-sites-create.component.ts +++ b/frontend/app/components/monitoring-sites-create/monitoring-sites-create.component.ts @@ -1,14 +1,16 @@ import { Component, OnInit, ViewChild } from '@angular/core'; -import { FormService } from '../../services/form.service'; -import { FormGroup, FormBuilder } from '@angular/forms'; -import { ISite, ISiteType } from '../../interfaces/geom'; -import { SitesService } from '../../services/api-geom.service'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; + +import { endPoints } from '../../enum/endpoints'; +import { ISite, ISiteType } from '../../interfaces/geom'; import { IobjObs, ObjDataType } from '../../interfaces/objObs'; -import { MonitoringFormComponentG } from '../monitoring-form-g/monitoring-form.component-g'; +import { SitesService } from '../../services/api-geom.service'; +import { FormService } from '../../services/form.service'; import { ObjectService } from '../../services/object.service'; import { JsonData } from '../../types/jsondata'; -import { endPoints } from '../../enum/endpoints'; +import { MonitoringFormComponentG } from '../monitoring-form-g/monitoring-form.component-g'; import { IPaginated } from '../../interfaces/page'; @Component({ @@ -28,30 +30,41 @@ export class MonitoringSitesCreateComponent implements OnInit { @ViewChild('subscritionObjConfig') monitoringFormComponentG: MonitoringFormComponentG; objToCreate: IobjObs; - + urlRelative: string; constructor( private _formService: FormService, private _formBuilder: FormBuilder, private siteService: SitesService, + private route: ActivatedRoute, private _objService: ObjectService ) {} ngOnInit() { + this.urlRelative = this.removeLastPart(this.route.snapshot['_routerState'].url); this._objService.currentObjSelected.subscribe((objParent) => { this.id_sites_group = objParent.id_sites_group; - this._formService.dataToCreate({ - module: 'generic', - objectType: 'site', - id_sites_group: this.id_sites_group, - id_relationship: ['id_sites_group', 'types_site'], - endPoint: endPoints.sites, - objSelected: {}, - }); + this._formService.dataToCreate( + { + module: 'generic', + objectType: 'site', + id: null, + id_sites_group: this.id_sites_group, + id_relationship: ['id_sites_group', 'types_site'], + endPoint: endPoints.sites, + objSelected: objParent.objectType, + }, + this.urlRelative + ); this.form = this._formBuilder.group({}); this.funcToFilt = this.partialfuncToFilt.bind(this); }); } + removeLastPart(url: string): string { + return url.slice(0, url.lastIndexOf('/')); + } + + partialfuncToFilt( pageNumber: number, limit: number, diff --git a/frontend/app/components/monitoring-sites-edit/monitoring-sites-edit.component.css b/frontend/app/components/monitoring-sites-edit/monitoring-sites-edit.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/app/components/monitoring-sites-edit/monitoring-sites-edit.component.html b/frontend/app/components/monitoring-sites-edit/monitoring-sites-edit.component.html new file mode 100644 index 000000000..cc95c530c --- /dev/null +++ b/frontend/app/components/monitoring-sites-edit/monitoring-sites-edit.component.html @@ -0,0 +1,13 @@ + +
+ +
diff --git a/frontend/app/components/monitoring-sites-edit/monitoring-sites-edit.component.ts b/frontend/app/components/monitoring-sites-edit/monitoring-sites-edit.component.ts new file mode 100644 index 000000000..11dc7010a --- /dev/null +++ b/frontend/app/components/monitoring-sites-edit/monitoring-sites-edit.component.ts @@ -0,0 +1,73 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; +import { Observable } from 'rxjs'; + +import { ISite } from '../../interfaces/geom'; +import { IobjObs, ObjDataType } from '../../interfaces/objObs'; +import { SitesService } from '../../services/api-geom.service'; +import { FormService } from '../../services/form.service'; +import { ObjectService } from '../../services/object.service'; +import { JsonData } from '../../types/jsondata'; +import { MonitoringFormComponentG } from '../monitoring-form-g/monitoring-form.component-g'; + +@Component({ + selector: 'monitoring-sites-edit', + templateUrl: './monitoring-sites-edit.component.html', + styleUrls: ['./monitoring-sites-edit.component.css'], +}) +export class MonitoringSitesEditComponent implements OnInit { + site: ISite; + form: FormGroup; + paramToFilt: string = 'label'; + funcToFilt: Function; + titleBtn: string = 'Choix des types de sites'; + placeholderText: string = 'Sélectionnez les types de site'; + id_sites_group: number; + types_site: string[]; + @ViewChild('subscritionObjConfig') + monitoringFormComponentG: MonitoringFormComponentG; + objToCreate: IobjObs; + + constructor( + private _formService: FormService, + private _formBuilder: FormBuilder, + private siteService: SitesService, + private _Activatedroute: ActivatedRoute, + private _objService: ObjectService + ) {} + + ngOnInit() { + + this._objService.currentObjSelected.subscribe((objParent) => { + this.id_sites_group = objParent.id_sites_group; + // this._formService.changeDataSub({ module: "generic", objectType: "site", id_sites_group : this.id_sites_group, id_relationship: ['id_sites_group','types_site'],endPoint:endPoints.sites,objSelected:objParent.objectType}); + this.form = this._formBuilder.group({}); + this.funcToFilt = this.partialfuncToFilt.bind(this); + }); + } + + partialfuncToFilt(pageNumber: number, limit: number, valueToFilter: string): Observable { + return this.siteService.getTypeSites(pageNumber, limit, { + label_fr: valueToFilter, + sort_dir: 'desc', + }); + } + + onSendConfig(config: JsonData): void { + config = this.addTypeSiteListIds(config); + this.monitoringFormComponentG.getConfigFromBtnSelect(config); + } + + addTypeSiteListIds(config: JsonData): JsonData { + if (config && config.length != 0) { + config['types_site'] = []; + for (const key in config) { + if ('id_nomenclature_type_site' in config[key]) { + config['types_site'].push(config[key]['id_nomenclature_type_site']); + } + } + } + return config; + } +} diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.html b/frontend/app/components/monitoring-sites/monitoring-sites.component.html index 0f495dfae..7c7b3aa9f 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.html +++ b/frontend/app/components/monitoring-sites/monitoring-sites.component.html @@ -2,6 +2,7 @@ *ngIf="!bEdit" [(bEdit)]="bEdit" [selectedObj]="sitesGroup" + [newParentType]="objParent" > ; + objParent: any; constructor( private _sitesGroupService: SitesGroupService, @@ -53,19 +51,23 @@ export class MonitoringSitesComponent ngOnInit() { this.objForm = this._formBuilder.group({}); - this._objService.changeObjectType(this._siteService.objectObs); + // this._sitesGroupService.init() + this._objService.changeObjectTypeParent(this._sitesGroupService.objectObs, true); + this._objService.currentObjectTypeParent.subscribe((objParent) => { + this.objParent = objParent; + }); + this._objService.changeObjectType(this._siteService.objectObs, true); this.initSite(); } initSite() { this._Activatedroute.params .pipe( - map((params) => params["id"] as number), + map((params) => params['id'] as number), tap((id: number) => { - this._geojsonService.getSitesGroupsChildGeometries( - this.onEachFeatureSite(), - { id_sites_group: id } - ); + this._geojsonService.getSitesGroupsChildGeometries(this.onEachFeatureSite(), { + id_sites_group: id, + }); }), mergeMap((id: number) => forkJoin({ @@ -95,9 +97,7 @@ export class MonitoringSitesComponent ); } ngOnDestroy() { - this._geojsonService.removeFeatureGroup( - this._geojsonService.sitesFeatureGroup - ); + this._geojsonService.removeFeatureGroup(this._geojsonService.sitesFeatureGroup); this._geojsonService.removeFeatureGroup(this.siteGroupLayer); } @@ -107,7 +107,7 @@ export class MonitoringSitesComponent const popup = setPopup( baseUrl, feature.properties.id_base_site, - "Site :" + feature.properties.base_site_name + 'Site :' + feature.properties.base_site_name ); layer.bindPopup(popup); }; @@ -128,7 +128,7 @@ export class MonitoringSitesComponent seeDetails($event) { this._objService.changeObjectTypeParent(this._siteService.objectObs, true); - this.router.navigate([`sites/${$event.id_base_site}`], { + this.router.navigate([`site/${$event.id_base_site}`], { relativeTo: this._Activatedroute, }); } 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 index 07c4e379b..3e6b774cc 100644 --- a/frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.ts +++ b/frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.ts @@ -1,29 +1,39 @@ -import { Component, OnInit } from "@angular/core"; -import { FormService } from "../../services/form.service"; -import { FormGroup, FormBuilder } from "@angular/forms"; -import { ISitesGroup } from "../../interfaces/geom"; -import { endPoints } from "../../enum/endpoints"; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; + +import { endPoints } from '../../enum/endpoints'; +import { ISitesGroup } from '../../interfaces/geom'; +import { FormService } from '../../services/form.service'; @Component({ - selector: "monitoring-sitesgroups-create", - templateUrl: "./monitoring-sitesgroups-create.component.html", - styleUrls: ["./monitoring-sitesgroups-create.component.css"], + 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; + urlRelative: string; constructor( private _formService: FormService, - private _formBuilder: FormBuilder + private _formBuilder: FormBuilder, + private route: ActivatedRoute ) {} ngOnInit() { - this._formService.dataToCreate({ - module: "generic", - objectType: "sites_group", - endPoint:endPoints.sites_groups, - objSelected: {} - }); + // Remove "create" segmentUrl + this.urlRelative = '/monitorings'; + this._formService.dataToCreate( + { + module: 'generic', + objectType: 'sites_group', + id: null, + endPoint: endPoints.sites_groups, + objSelected: {}, + }, + this.urlRelative + ); this.form = this._formBuilder.group({}); } } diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index d7dc6a662..a940fc589 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -125,5 +125,4 @@ export class MonitoringSitesGroupsComponent onSelect($event) { this.geojsonService.selectSitesGroupLayer($event); } - onObjChanged($event) {} } diff --git a/frontend/app/components/monitoring-visits/monitoring-visits.component.css b/frontend/app/components/monitoring-visits/monitoring-visits.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/app/components/monitoring-visits/monitoring-visits.component.html b/frontend/app/components/monitoring-visits/monitoring-visits.component.html new file mode 100644 index 000000000..dc350d016 --- /dev/null +++ b/frontend/app/components/monitoring-visits/monitoring-visits.component.html @@ -0,0 +1,8 @@ + +
+ + + +
\ No newline at end of file diff --git a/frontend/app/components/monitoring-visits/monitoring-visits.component.ts b/frontend/app/components/monitoring-visits/monitoring-visits.component.ts new file mode 100644 index 000000000..1f4f2f27b --- /dev/null +++ b/frontend/app/components/monitoring-visits/monitoring-visits.component.ts @@ -0,0 +1,92 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { forkJoin } from 'rxjs'; +import { map, mergeMap } from 'rxjs/operators'; + +import { MonitoringGeomComponent } from '../../class/monitoring-geom-component'; +import { ISite } from '../../interfaces/geom'; +import { IPage, IPaginated } from '../../interfaces/page'; +import { IVisit } from '../../interfaces/visit'; +import { SitesService, VisitsService } from '../../services/api-geom.service'; +import { GeoJSONService } from '../../services/geojson.service'; +import { ObjectService } from '../../services/object.service'; +import { JsonData } from '../../types/jsondata'; + +@Component({ + selector: 'monitoring-visits', + templateUrl: './monitoring-visits.component.html', + styleUrls: ['./monitoring-visits.component.css'], +}) +export class MonitoringVisitsComponent extends MonitoringGeomComponent implements OnInit { + site: ISite; + @Input() visits: IVisit[]; + @Input() page: IPage; + // colsname: typeof columnNameVisit = columnNameVisit; + objectType: string; + bEdit: boolean; + objForm: FormGroup; + @Input() colsname; + objParent: any; + + constructor( + private _sites_service: SitesService, + private _visits_service: VisitsService, + private _objService: ObjectService, + public geojsonService: GeoJSONService, + private router: Router, + private _Activatedroute: ActivatedRoute, + private _formBuilder: FormBuilder + ) { + super(); + this.getAllItemsCallback = this.getVisits; + this.objectType = 'sites'; + } + + ngOnInit() { + this.objForm = this._formBuilder.group({}); + this._objService.changeObjectTypeParent(this._sites_service.objectObs, true); + this._objService.currentObjectTypeParent.subscribe((objParent) => (this.objParent = objParent)); + + this._objService.changeObjectType(this._visits_service.objectObs); + this._Activatedroute.params + .pipe( + map((params) => params['id'] as number), + mergeMap((id: number) => + forkJoin({ + site: this._sites_service.getById(id), + visits: this._visits_service.get(1, this.limit, { + id_base_site: id, + }), + }) + ) + ) + .subscribe((data: { site: ISite; visits: IPaginated }) => { + this.site = data.site; + this.setVisits(data.visits); + this.baseFilters = { id_base_site: this.site.id_base_site }; + }); + } + + getVisits(page: number, filters: JsonData) { + this._visits_service + .get(page, this.limit, filters) + .subscribe((visits: IPaginated) => this.setVisits(visits)); + } + + setVisits(visits) { + this.visits = visits.items; + this.page = { + page: visits.page - 1, + count: visits.count, + limit: visits.limit, + }; + this.colsname = this._visits_service.objectObs.dataTable.colNameObj; + } + + seeDetails($event) { + this.router.navigate([ + `monitorings/object/${$event.module.module_code}/visit/${$event.id_base_visit}`, + ]); + } +} diff --git a/frontend/app/enum/endpoints.ts b/frontend/app/enum/endpoints.ts index fc7f634af..1c278d69b 100644 --- a/frontend/app/enum/endpoints.ts +++ b/frontend/app/enum/endpoints.ts @@ -2,4 +2,5 @@ export enum endPoints { sites_groups = "sites_groups", sites = "sites", + visits = "visits", } \ No newline at end of file diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index bb57b9cbe..a3da05a3e 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -47,10 +47,13 @@ import { SitesGroupService, SitesService, ApiGeomService, + VisitsService, } from "./services/api-geom.service"; import { MonitoringSitesGroupsCreateComponent } from "./components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component"; import { MonitoringSitesCreateComponent } from "./components/monitoring-sites-create/monitoring-sites-create.component"; import { BtnSelectComponent } from "./components/btn-select/btn-select.component"; +import { MonitoringSitesEditComponent } from "./components/monitoring-sites-edit/monitoring-sites-edit.component"; +import { MonitoringVisitsComponent } from "./components/monitoring-visits/monitoring-visits.component"; // my module routing const routes: Routes = [ @@ -92,6 +95,17 @@ const routes: Routes = [ path: "create", component: MonitoringSitesCreateComponent, }, + { + path: "site/:id", + component: MonitoringVisitsComponent, + children: [ + { + path: "edit", + component: MonitoringSitesEditComponent, + }, + ] + }, + ], }, ], @@ -118,7 +132,9 @@ const routes: Routes = [ MonitoringFormComponentG, MonitoringSitesGroupsCreateComponent, MonitoringSitesCreateComponent, - BtnSelectComponent + MonitoringSitesEditComponent, + BtnSelectComponent, + MonitoringVisitsComponent ], imports: [ GN2CommonModule, @@ -151,6 +167,7 @@ const routes: Routes = [ FormService, ObjectService, ApiGeomService, + VisitsService ], bootstrap: [ModulesComponent], schemas: [ diff --git a/frontend/app/interfaces/geom.ts b/frontend/app/interfaces/geom.ts index 51ac5de25..eea5242ce 100644 --- a/frontend/app/interfaces/geom.ts +++ b/frontend/app/interfaces/geom.ts @@ -55,3 +55,9 @@ export interface ISiteType { id_nomenclature_type_site: number; label: string; } + +export interface ISiteType { + config:JsonData, + id_nomenclature_type_site:number, + label:string +} \ No newline at end of file diff --git a/frontend/app/interfaces/objObs.ts b/frontend/app/interfaces/objObs.ts index 927a65127..01f59d3e2 100644 --- a/frontend/app/interfaces/objObs.ts +++ b/frontend/app/interfaces/objObs.ts @@ -1,16 +1,17 @@ import { endPoints } from "../enum/endpoints"; import { JsonData } from "../types/jsondata"; import { ISite, ISitesGroup } from "./geom"; - -export type ObjDataType = ISite | ISitesGroup | JsonData; +import { IVisit } from "./visit"; +export type ObjDataType = ISite | ISitesGroup | IVisit | JsonData ; export interface IobjObs { properties: ObjDataType; endPoint: endPoints; - objectType: "site" | "sites_group"; + objectType: "site" | "sites_group" | "visits"; label: string; addObjLabel: string; editObjLabel: string; + addChildLabel: string; id: string | null; moduleCode: string; schema: JsonData; diff --git a/frontend/app/interfaces/object.ts b/frontend/app/interfaces/object.ts new file mode 100644 index 000000000..3e52f3935 --- /dev/null +++ b/frontend/app/interfaces/object.ts @@ -0,0 +1,20 @@ +import { JsonData } from "../types/jsondata"; +import { IPaginated } from "./page"; +import { GeoJSON } from "geojson"; +import { Observable } from "rxjs"; +import { Resp } from "../types/response"; + +export interface IObject { + data: JsonData; +} + +export interface IService { + get(limit: number, page: number, params: JsonData): Observable>; + create(postdata: T): Observable; + patch(id: number, updatedData: T): Observable; + // delete(obj: IGeomObject) +} + +export interface IGeomService extends IService { + get_geometries(params: JsonData): Observable; +} diff --git a/frontend/app/interfaces/visit.ts b/frontend/app/interfaces/visit.ts new file mode 100644 index 000000000..0404ee6e8 --- /dev/null +++ b/frontend/app/interfaces/visit.ts @@ -0,0 +1,18 @@ +import { JsonData } from "../types/jsondata"; +import { IGeomObject } from "./geom"; + +export interface IVisit extends IGeomObject { + pk:number; + comments: string; + data: JsonData; + id_base_visit: number; + id_module: number; + id_nomenclature_grp_typ: number; + id_nomenclature_tech_collect_campanule: number; + meta_create_date: Date; + meta_update_date: Date; + nb_observations: number; + uuid_base_visit: string; + visit_date_max: Date; + visit_date_min: Date; +} diff --git a/frontend/app/services/api-geom.service.ts b/frontend/app/services/api-geom.service.ts index 47fbdd4ae..92a39cf73 100644 --- a/frontend/app/services/api-geom.service.ts +++ b/frontend/app/services/api-geom.service.ts @@ -10,6 +10,7 @@ import { Resp } from '../types/response'; import { Utils } from '../utils/utils'; import { CacheService } from './cache.service'; import { ConfigJsonService } from './config-json.service'; +import { IVisit } from '../interfaces/visit'; @Injectable() export class ApiGeomService implements IGeomService { @@ -23,7 +24,7 @@ export class ApiGeomService implements IGeomService { this.init(this.endPoint, this.objectObs); } - init(endPoint, objectObjs) { + init(endPoint:endPoints, objectObjs: IobjObs) { this.endPoint = endPoint; this.objectObs = objectObjs; // this.endPoint = endPoints.sites_groups; @@ -50,8 +51,8 @@ export class ApiGeomService implements IGeomService { page: number = 1, limit: number = 10, params: JsonData = {} - ): Observable> { - return this._cacheService.request>>( + ): Observable> { + return this._cacheService.request>>( 'get', this.endPoint, { @@ -60,7 +61,7 @@ export class ApiGeomService implements IGeomService { ); } - getById(id: number): Observable { + getById(id: number): Observable { return this._cacheService.request>( 'get', `${this.endPoint}/${id}` @@ -77,7 +78,7 @@ export class ApiGeomService implements IGeomService { ); } - patch(id: number, updatedData: { properties: ISitesGroup | ISite }): Observable { + patch(id: number, updatedData: { properties: ISitesGroup | ISite | IVisit }): Observable { return this._cacheService.request('patch', `${this.endPoint}/${id}`, { postData: updatedData, }); @@ -108,6 +109,7 @@ export class SitesGroupService extends ApiGeomService { label: 'groupe de site', addObjLabel: 'Ajouter un nouveau groupe de site', editObjLabel: 'Editer le groupe de site', + addChildLabel: 'Ajouter un site', id: null, moduleCode: 'generic', schema: {}, @@ -184,6 +186,7 @@ export class SitesService extends ApiGeomService { label: 'site', addObjLabel: 'Ajouter un nouveau site', editObjLabel: 'Editer le site', + addChildLabel: 'Ajouter une visite', id: null, moduleCode: 'generic', schema: {}, @@ -256,3 +259,67 @@ export class SitesService extends ApiGeomService { return 'le site'; } } + +@Injectable() +export class VisitsService extends ApiGeomService { + constructor(_cacheService: CacheService, _configJsonService: ConfigJsonService) { + super(_cacheService, _configJsonService); + } + init(): void { + this.endPoint = endPoints.visits; + this.objectObs = { + properties: {}, + endPoint: endPoints.visits, + objectType: 'visits', + label: 'visite', + addObjLabel: 'Ajouter une nouvelle visite', + editObjLabel: 'Editer la visite', + addChildLabel: 'Ajouter une observation', + id: null, + moduleCode: 'generic', + schema: {}, + template: { + fieldNames: [], + fieldLabels: {}, + fieldNamesList: [], + fieldDefinitions: {}, + }, + dataTable: { colNameObj: {} }, + }; + this._configJsonService + .init(this.objectObs.moduleCode) + .pipe() + .subscribe(() => { + const fieldNames = this._configJsonService.configModuleObjectParam( + this.objectObs.moduleCode, + this.objectObs.objectType, + 'display_properties' + ); + const fieldNamesList = this._configJsonService.configModuleObjectParam( + this.objectObs.moduleCode, + this.objectObs.objectType, + 'display_list' + ); + const schema = this._configJsonService.schema( + this.objectObs.moduleCode, + this.objectObs.objectType + ); + const fieldLabels = this._configJsonService.fieldLabels(schema); + const fieldDefinitions = this._configJsonService.fieldDefinitions(schema); + this.objectObs.template.fieldNames = fieldNames; + this.objectObs.template.fieldNamesList = fieldNamesList; + this.objectObs.schema = schema; + this.objectObs.template.fieldLabels = fieldLabels; + this.objectObs.template.fieldDefinitions = fieldDefinitions; + this.objectObs.template.fieldNamesList = fieldNamesList; + this.objectObs.dataTable.colNameObj = Utils.toObject(fieldNamesList, fieldLabels); + }); + } + addObjectType(): string { + return " une nouvelle visite"; + } + + editObjectType(): string { + return "la visite"; + } +} \ No newline at end of file diff --git a/frontend/app/services/config-json.service.ts b/frontend/app/services/config-json.service.ts index 282910bd6..3d7e9a42f 100644 --- a/frontend/app/services/config-json.service.ts +++ b/frontend/app/services/config-json.service.ts @@ -6,6 +6,7 @@ import { of } from 'rxjs'; import { ConfigService } from './config.service'; + @Injectable() export class ConfigJsonService extends ConfigService { diff --git a/frontend/app/services/form.service.ts b/frontend/app/services/form.service.ts index 0499fccad..c8d6b0ff5 100644 --- a/frontend/app/services/form.service.ts +++ b/frontend/app/services/form.service.ts @@ -2,8 +2,8 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable, forkJoin, of } from 'rxjs'; import { concatMap } from 'rxjs/operators'; -import { IobjObs, ObjDataType } from '../interfaces/objObs'; import { ISite, ISitesGroup } from '../interfaces/geom'; +import { IobjObs, ObjDataType } from '../interfaces/objObs'; import { JsonData } from '../types/jsondata'; import { Utils } from '../utils/utils'; import { MonitoringObjectService } from './monitoring-object.service'; @@ -20,22 +20,28 @@ export class FormService { constructor(private _objService: MonitoringObjectService) {} // TODO: voir si nécessaire de garder ça (objService permet d'avoir le bon objet ? et sinon modifier pour obtenir ce qu'il faut en formulaire) - changeDataSub(newDat: JsonData, objectType: string,endPoint:string,objSelected:IobjObs, moduleCode: string = 'generic') { + changeDataSub( + newDat: JsonData, + objectType: string, + endPoint: string, + moduleCode: string = 'generic' + ) { this.properties = newDat; newDat.moduleCode = moduleCode; newDat.objectType = objectType; newDat.endPoint = endPoint; - newDat.objSelect = objSelected this.dataSub.next(newDat); } - dataToCreate(newDat: JsonData, moduleCode: string = 'generic') { + dataToCreate(newDat: JsonData, urlRelative: string, moduleCode: string = 'generic') { newDat[moduleCode] = {}; newDat.moduleCode = moduleCode; + newDat.urlRelative = urlRelative; this.dataSub.next(newDat); } formValues(obj): Observable { + // const {properties ,remainaing} = obj const properties = Utils.copy(this.properties); const observables = {}; const schema = obj[obj.moduleCode];