diff --git a/backend/gn_module_monitoring/config/repositories.py b/backend/gn_module_monitoring/config/repositories.py index 7dfae2456..832335874 100644 --- a/backend/gn_module_monitoring/config/repositories.py +++ b/backend/gn_module_monitoring/config/repositories.py @@ -120,6 +120,15 @@ def config_object_from_files(module_code, object_type, custom=None, is_sites_gro generic_config_object["generic"]["types_site"] = { "type_widget": "datalist", "attribut_label": "Type(s) de site", + "type_util": "types_site", + "keyValue": "id_nomenclature_type_site", + "keyLabel": "label", + "multiple": True, + "api": "monitorings/modules/generic/types_sites", + "application": "GeoNature", + "required": True, + "nullDefault": True, + "definition": "Permet de n'avoir que les types de site lié au module", } # if object_type == "site" and custom is not None: @@ -144,6 +153,8 @@ def get_config(module_code=None, force=False): alors la configuration est récupéré depuis current_app.config sinon la config est recupérée depuis les fichiers du dossier de configuration et stockée dans current_app.config """ + if module_code == "MONITORINGS": + module_code = "generic" module_code = module_code if module_code else "generic" module_confg_dir_path = monitoring_module_config_path(module_code) diff --git a/backend/gn_module_monitoring/migrations/a5498a5f6022_declare_available_types_sites_permissions.py b/backend/gn_module_monitoring/migrations/34253c8fa9b9_declare_available_types_sites_.py similarity index 70% rename from backend/gn_module_monitoring/migrations/a5498a5f6022_declare_available_types_sites_permissions.py rename to backend/gn_module_monitoring/migrations/34253c8fa9b9_declare_available_types_sites_.py index a6b44ed34..d2027f0d5 100644 --- a/backend/gn_module_monitoring/migrations/a5498a5f6022_declare_available_types_sites_permissions.py +++ b/backend/gn_module_monitoring/migrations/34253c8fa9b9_declare_available_types_sites_.py @@ -1,18 +1,17 @@ -""" declare available types sites permissions +"""declare available types sites permissions -Revision ID: a5498a5f6022 -Revises: fc90d31c677f -Create Date: 2024-02-01 10:42:28.268643 +Revision ID: 34253c8fa9b9 +Revises: 0defdace9997 +Create Date: 2024-07-11 16:44:23.736722 """ - from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = "a5498a5f6022" -down_revision = "fc90d31c677f" +revision = '34253c8fa9b9' +down_revision = '0defdace9997' branch_labels = None depends_on = None @@ -26,11 +25,7 @@ def upgrade(): description_object ) VALUES - ('TYPES_SITES','Types de sites à associer aux protocoles du module MONITORINGS'),('GNM_SITES', 'Permissions sur les sites'), - ('GNM_VISITES', 'Permissions sur les visites'), - ('GNM_OBSERVATIONS', 'Permissions sur les observation'), - ('GNM_GRP_SITES', 'Permissions sur les groupes de sites') - ON CONFLICT DO NOTHING; + ('TYPES_SITES','Types de sites à associer aux protocoles du module MONITORINGS') """ ) op.execute( @@ -56,14 +51,14 @@ def upgrade(): ('MONITORINGS', 'TYPES_SITES', 'C', False, 'Créer des types de site'), ('MONITORINGS', 'TYPES_SITES', 'U', False, 'Modifier des types de site'), ('MONITORINGS', 'TYPES_SITES', 'D', False, 'Supprimer des types de site'), - ('MONITORINGS', 'GNM_SITES', 'R', True, 'Accéder aux sites'), - ('MONITORINGS', 'GNM_SITES', 'C', True, 'Créer des sites'), - ('MONITORINGS', 'GNM_SITES', 'U', True, 'Modifier des sites'), - ('MONITORINGS', 'GNM_SITES', 'D', True, 'Supprimer des sites'), - ('MONITORINGS', 'GNM_GRP_SITES', 'R', True, 'Accéder aux groupes de sites'), - ('MONITORINGS', 'GNM_GRP_SITES', 'C', True, 'Créer des groupes de sites'), - ('MONITORINGS', 'GNM_GRP_SITES', 'U', True, 'Modifier des groupes de sites'), - ('MONITORINGS', 'GNM_GRP_SITES', 'D', True, 'Supprimer des groupes de sites') + ('MONITORINGS', 'MONITORINGS_SITES', 'R', True, 'Accéder aux sites'), + ('MONITORINGS', 'MONITORINGS_SITES', 'C', True, 'Créer des sites'), + ('MONITORINGS', 'MONITORINGS_SITES', 'U', True, 'Modifier des sites'), + ('MONITORINGS', 'MONITORINGS_SITES', 'D', True, 'Supprimer des sites'), + ('MONITORINGS', 'MONITORINGS_GRP_SITES', 'R', True, 'Accéder aux groupes de sites'), + ('MONITORINGS', 'MONITORINGS_GRP_SITES', 'C', True, 'Créer des groupes de sites'), + ('MONITORINGS', 'MONITORINGS_GRP_SITES', 'U', True, 'Modifier des groupes de sites'), + ('MONITORINGS', 'MONITORINGS_GRP_SITES', 'D', True, 'Supprimer des groupes de sites') ) AS v (module_code, object_code, action_code, scope_filter, label) JOIN gn_commons.t_modules m ON m.module_code = v.module_code @@ -107,7 +102,7 @@ def upgrade(): """ INSERT INTO gn_permissions.t_objects (code_object, description_object) VALUES - ('GNM_MODULES', 'Permissions sur les modules') + ('MONITORINGS_MODULES', 'Permissions sur les modules') ON CONFLICT DO NOTHING ; """ @@ -129,7 +124,7 @@ def downgrade(): pa.id_object IN ( SELECT to2.id_object FROM gn_permissions.t_objects to2 - WHERE code_object IN ('TYPES_SITES') + WHERE code_object IN ('TYPES_SITES', 'MONITORINGS_SITES', 'MONITORINGS_GRP_SITES') ) """ ) @@ -141,7 +136,7 @@ def downgrade(): USING gn_permissions.t_objects o WHERE p.id_object = o.id_object - AND o.code_object IN ('TYPES_SITES') + AND o.code_object IN ('TYPES_SITES', 'MONITORINGS_SITES', 'MONITORINGS_GRP_SITES', 'MONITORINGS_MODULES') ; """ ) @@ -150,7 +145,7 @@ def downgrade(): """ DELETE FROM gn_permissions.t_objects - WHERE code_object IN ('TYPES_SITES') + WHERE code_object IN ('TYPES_SITES', 'MONITORINGS_SITES', 'MONITORINGS_GRP_SITES', 'MONITORINGS_MODULES') ; """ - ) + ) \ No newline at end of file diff --git a/backend/gn_module_monitoring/migrations/3ffeea74a9dd_rename_gnm__to_monitorings_.py b/backend/gn_module_monitoring/migrations/3ffeea74a9dd_rename_gnm__to_monitorings_.py index 5fccb1fa4..9d694e7b7 100644 --- a/backend/gn_module_monitoring/migrations/3ffeea74a9dd_rename_gnm__to_monitorings_.py +++ b/backend/gn_module_monitoring/migrations/3ffeea74a9dd_rename_gnm__to_monitorings_.py @@ -12,7 +12,7 @@ # revision identifiers, used by Alembic. revision = "3ffeea74a9dd" -down_revision = "a5498a5f6022" +down_revision = "fc90d31c677f" branch_labels = None depends_on = None diff --git a/backend/gn_module_monitoring/migrations/be30fb5c1a56_add_site_group_object_for_monitoring_.py b/backend/gn_module_monitoring/migrations/be30fb5c1a56_add_site_group_object_for_monitoring_.py new file mode 100644 index 000000000..e7230d72a --- /dev/null +++ b/backend/gn_module_monitoring/migrations/be30fb5c1a56_add_site_group_object_for_monitoring_.py @@ -0,0 +1,37 @@ +"""add site group object for monitoring module + +Revision ID: be30fb5c1a56 +Revises: 34253c8fa9b9 +Create Date: 2024-07-12 14:42:28.611638 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'be30fb5c1a56' +down_revision = '34253c8fa9b9' +branch_labels = None +depends_on = None + + +def upgrade(): + op.execute( + """ + INSERT INTO gn_permissions.cor_object_module (id_object ,id_module) + VALUES + ((select id_object from gn_permissions.t_objects where code_object = 'MONITORINGS_GRP_SITES'), + (select id_module from gn_commons.t_modules where module_code = 'MONITORINGS')); + """ + ) + + +def downgrade(): + op.execute( + """ + DELETE FROM gn_permissions.cor_object_module + WHERE id_object = (select id_object from gn_permissions.t_objects where code_object = 'MONITORINGS_GRP_SITES') + AND id_module = (select id_module from gn_commons.t_modules where module_code = 'MONITORINGS'); + """ + ) diff --git a/backend/gn_module_monitoring/monitoring/base.py b/backend/gn_module_monitoring/monitoring/base.py index 2816414ab..37233953f 100644 --- a/backend/gn_module_monitoring/monitoring/base.py +++ b/backend/gn_module_monitoring/monitoring/base.py @@ -72,7 +72,11 @@ class MonitoringObjectBase: cruved = {} def __init__(self, module_code, object_type, config, id=None, model=None): + if module_code == "generic": + module_code = "MONITORINGS" + self._module_code = module_code + self._object_type = object_type self._id = id @@ -126,7 +130,6 @@ def config_param(self, param_name): renverra 'Site' """ - return self._config[self._object_type].get(param_name) def get_value_generic(self, param_name): @@ -156,7 +159,7 @@ def parent_type(self): def parent_config_param(self, param_name): parent_type = self.parent_type() if parent_type: - return self.config_param(param_name) + return self._config[parent_type].get(param_name) def config_schema(self, type_schema="all"): """ diff --git a/backend/gn_module_monitoring/monitoring/geom.py b/backend/gn_module_monitoring/monitoring/geom.py index 5b02f4db9..be89938eb 100644 --- a/backend/gn_module_monitoring/monitoring/geom.py +++ b/backend/gn_module_monitoring/monitoring/geom.py @@ -22,7 +22,10 @@ def serialize(self, depth, is_child=False): if hasattr(self._model, "types_site"): # TODO: performance? types_site = [typ.nomenclature.label_fr for typ in self._model.types_site] + # On récupères tous les ids des types de site associé au site (nécessaire pour garder l'ensemble des types de site associé à un site) + ids_types_site = [typ.id_nomenclature_type_site for typ in self._model.types_site] monitoring_object_dict["properties"]["types_site"] = types_site + monitoring_object_dict["properties"]["ids_types_site"] = ids_types_site # On ne sérialise la géométrie que si l'objet n'est pas un enfant # si l'objet est de type enfant il va être affiché au niveau du tableau diff --git a/backend/gn_module_monitoring/monitoring/objects.py b/backend/gn_module_monitoring/monitoring/objects.py index 983267285..78b9eaae0 100644 --- a/backend/gn_module_monitoring/monitoring/objects.py +++ b/backend/gn_module_monitoring/monitoring/objects.py @@ -26,6 +26,9 @@ class MonitoringSite(MonitoringObjectGeom): """ def preprocess_data(self, properties, data=[]): + if all(isinstance(x, int) for x in properties["types_site"]): + return + # TODO: VERIFIER CE QUI EST NECESSAIRE A GARDER ICI if len(data) != 0: if len(data["types_site"]) > 0 and all(isinstance(x, int) for x in data["types_site"]): properties["types_site"] = data["types_site"] diff --git a/backend/gn_module_monitoring/monitoring/repositories.py b/backend/gn_module_monitoring/monitoring/repositories.py index 812ec806f..a7f79eff1 100644 --- a/backend/gn_module_monitoring/monitoring/repositories.py +++ b/backend/gn_module_monitoring/monitoring/repositories.py @@ -29,9 +29,7 @@ def get(self, value=None, field_name=None, depth=0): try: Model = self.MonitoringModel() - req = select(Model) - # Test pour mettre les relations à joined # if depth > 0: # options = [] diff --git a/backend/gn_module_monitoring/monitoring/serializer.py b/backend/gn_module_monitoring/monitoring/serializer.py index e4d8d5f1b..3d0bfaba7 100644 --- a/backend/gn_module_monitoring/monitoring/serializer.py +++ b/backend/gn_module_monitoring/monitoring/serializer.py @@ -36,7 +36,8 @@ class MonitoringObjectSerializer(MonitoringObjectBase): def get_parent(self): parent_type = self.parent_type() - if not parent_type: + + if not parent_type or parent_type == "module": return if not self._parent: @@ -72,6 +73,13 @@ def flatten_specific_properties(self, properties, only=None): for attribut_name in self.config_schema(type_schema="specific"): if attribut_name in only or not only: properties[attribut_name] = data.get(attribut_name) + # Nécessaire pour récupérer tous les données des champs additionnels mêmes ceux non présents dans la config specific + # Nécessaire pour les récupérer coté frontend lors de l'envoie de l'objet (patch et post) + properties["additional_data_keys"] = [] + for prop in data: + if prop not in properties.keys(): + properties[prop] = data[prop] + properties["additional_data_keys"].append(prop) def unflatten_specific_properties(self, properties): data = {} @@ -80,7 +88,8 @@ def unflatten_specific_properties(self, properties): if attribut_name in properties: val = properties.pop(attribut_name) else: - # TODO évaluer l'incidence + # TODO [DEV-SUIVI-EOLIEN] évaluer l'incidence + # TODO [DEV-SUIVI-EOLIEN] Ici il faut exclure les properties liés à la config generic + aux propriétés du model # voir comment générer les proprités spécifiques # non définies dans le schéma val = None @@ -88,6 +97,19 @@ def unflatten_specific_properties(self, properties): if data: properties["data"] = data + else: + properties["data"] = {} + # On ajoute les propriétés associées aux types de site qui ne sont ni dans le schema specific ni dans generic ou appartenant au modèle + prop_remaining_to_check = list(properties.keys()) + + for prop in prop_remaining_to_check: + is_in_model = hasattr(self._model, prop) + if ( + not is_in_model + and prop not in self.config_schema("generic").keys() + and prop != "id_module" + ): + properties["data"][prop] = properties.pop(prop) def get_readable_list_object(self, relation_name, children_type): childs_model = monitoring_definitions.MonitoringModel(object_type=children_type) @@ -246,6 +268,7 @@ def serialize(self, depth=1, is_child=False): ] properties["id_parent"] = to_int(self.id_parent()) + monitoring_object_dict = { "properties": properties, "object_type": self._object_type, diff --git a/backend/gn_module_monitoring/routes/data_utils.py b/backend/gn_module_monitoring/routes/data_utils.py index 56e74fbe0..e95ef9de9 100644 --- a/backend/gn_module_monitoring/routes/data_utils.py +++ b/backend/gn_module_monitoring/routes/data_utils.py @@ -71,11 +71,11 @@ def get_init_data(module_code): """ renvoie les données nomenclatures, etc à précharger par le module """ - + if module_code == "MONITORINGS": + module_code = "generic" out = {} config = get_config(module_code, True) data = config.get("data") - if not data: return {} diff --git a/backend/gn_module_monitoring/routes/modules.py b/backend/gn_module_monitoring/routes/modules.py index 50043b72a..750c2e3b9 100644 --- a/backend/gn_module_monitoring/routes/modules.py +++ b/backend/gn_module_monitoring/routes/modules.py @@ -91,6 +91,9 @@ def get_modules_api(): @blueprint.route("/modules//types_sites", methods=["GET"]) def get_all_types_site_from_module_id(module_code): module = get_module("module_code", module_code) - types_site = query_all_types_site_from_module_id(module.id_module) + id_module = None + if module: + id_module = module.id_module + types_site = query_all_types_site_from_module_id(id_module) schema = BibTypeSiteSchema() return [schema.dump(res) for res in types_site] diff --git a/backend/gn_module_monitoring/routes/monitoring.py b/backend/gn_module_monitoring/routes/monitoring.py index 7a1c8c953..a6438cfb7 100644 --- a/backend/gn_module_monitoring/routes/monitoring.py +++ b/backend/gn_module_monitoring/routes/monitoring.py @@ -36,6 +36,9 @@ def set_current_module(endpoint, values): # recherche du sous-module courrant requested_module_code = values.get("module_code") or MODULE_CODE + if requested_module_code == "generic": + requested_module_code = "MONITORINGS" + current_module = DB.first_or_404( statement=select(TModules) .options(joinedload(TModules.objects)) @@ -62,7 +65,6 @@ def set_current_module(endpoint, values): ), description=f"No permission object with code {requested_permission_object_code} {endpoint}", ) - # si l'object de permission est associé au module => il devient l'objet courant # - sinon se sera 'ALL' par defaut for module_perm_object in current_module.objects: diff --git a/backend/gn_module_monitoring/utils/routes.py b/backend/gn_module_monitoring/utils/routes.py index 1e25daaa0..564345429 100644 --- a/backend/gn_module_monitoring/utils/routes.py +++ b/backend/gn_module_monitoring/utils/routes.py @@ -145,15 +145,12 @@ def query_all_types_site_from_site_id(id_site: int): def query_all_types_site_from_module_id(id_module: int = None): - query = ( - select(BibTypeSite) - .join( - cor_module_type, - BibTypeSite.id_nomenclature_type_site == cor_module_type.c.id_type_site, - ) - .join(TModules, cor_module_type.c.id_module == TModules.id_module) - ) + query = select(BibTypeSite) if id_module: + query = query.join( + cor_module_type, + BibTypeSite.id_nomenclature_type_site == cor_module_type.c.id_type_site, + ) query = query.where(cor_module_type.c.id_module == id_module) return DB.session.scalars(query).unique().all() diff --git a/frontend/app/class/breadCrumb.ts b/frontend/app/class/breadCrumb.ts index 33c8e312f..240bfee52 100644 --- a/frontend/app/class/breadCrumb.ts +++ b/frontend/app/class/breadCrumb.ts @@ -1,13 +1,13 @@ const getElementSiteGroupBC = { description: 'Liste des groupes de site', label: '', - url: 'sites_group', + url: 'object/generic/sites_group', }; const getElementSiteBC = { description: 'Liste des sites', label: '', - url: 'sites', + url: 'object/generic/site', }; export class breadCrumbBase { diff --git a/frontend/app/class/monitoring-object-base.ts b/frontend/app/class/monitoring-object-base.ts index 8daf362b1..0906d2d12 100644 --- a/frontend/app/class/monitoring-object-base.ts +++ b/frontend/app/class/monitoring-object-base.ts @@ -367,13 +367,24 @@ export class MonitoringObjectBase { queryParamsAddChildren['siteId'] = siteId || this.siteId; queryParamsAddChildren['parents_path'] = this.parentsPath.concat(this.objectType); - this._objService.navigate( - 'create_object', - this.moduleCode, - childrenType || this.uniqueChildrenType(), - null, - queryParamsAddChildren - ); + if (this.moduleCode == 'generic') { + this._objService.navigateGeneric( + 'object', + this.moduleCode, + childrenType || this.uniqueChildrenType(), + null, + 'create', + queryParamsAddChildren + ); + } else { + this._objService.navigate( + 'create_object', + this.moduleCode, + childrenType || this.uniqueChildrenType(), + null, + queryParamsAddChildren + ); + } } navigateToDetail(id = null, toEdit = false) { @@ -387,7 +398,6 @@ export class MonitoringObjectBase { // cas module if (this.objectType.includes('module')) { this.navigateToDetail(); - // autres cas } else { const parentType = this.parentType(); diff --git a/frontend/app/class/monitoring-object.ts b/frontend/app/class/monitoring-object.ts index 1074ee17a..b05388154 100644 --- a/frontend/app/class/monitoring-object.ts +++ b/frontend/app/class/monitoring-object.ts @@ -92,10 +92,10 @@ export class MonitoringObject extends MonitoringObjectBase { ); } - post(formValue, dataComplement = {}): Observable { + post(formValue): Observable { return this._objService .dataMonitoringObjectService() - .postObject(this.moduleCode, this.objectType, this.postData(formValue, dataComplement)) + .postObject(this.moduleCode, this.objectType, this.postData(formValue)) .pipe( mergeMap((postData) => { this.id = postData['id']; @@ -105,15 +105,10 @@ export class MonitoringObject extends MonitoringObjectBase { ); } - patch(formValue, dataComplement = {}) { + patch(formValue) { return this._objService .dataMonitoringObjectService() - .patchObject( - this.moduleCode, - this.objectType, - this.id, - this.postData(formValue, dataComplement) - ) + .patchObject(this.moduleCode, this.objectType, this.id, this.postData(formValue)) .pipe( mergeMap((postData) => { this._objService.setCache(this, postData); @@ -197,7 +192,7 @@ export class MonitoringObject extends MonitoringObjectBase { /** postData: obj -> from */ - postData(formValue, dataComplement) { + postData(formValue) { const propertiesData = {}; const schema = this.schema(); for (const attribut_name of Object.keys(schema)) { @@ -207,20 +202,31 @@ export class MonitoringObject extends MonitoringObjectBase { } propertiesData[attribut_name] = this._objService.fromForm(elem, formValue[attribut_name]); } + // On récupère les champs spécifiques qui ne sont ni dans la config spécifique, générique ou des types de sites sélectionnés + // Permet de garder les propriétés du site sur un autre protocole qui appelle ce site avec d'autres types de sites associés + if ('additional_data_keys' in formValue && formValue['additional_data_keys'].length > 0) { + for (const key of formValue['additional_data_keys']) { + propertiesData[key] = formValue[key]; + } + } let postData = {}; - if (Object.keys(dataComplement).length == 0) { - postData = { - properties: propertiesData, - // id_parent: this.parentId - }; - } else { - postData = { - properties: propertiesData, - dataComplement: dataComplement, - // id_parent: this.parentId - }; - } + postData = { + properties: propertiesData, + // id_parent: this.parentId + }; + // if (Object.keys(dataComplement).length == 0) { + // postData = { + // properties: propertiesData, + // // id_parent: this.parentId + // }; + // } else { + // postData = { + // properties: propertiesData, + // dataComplement: dataComplement, + // // id_parent: this.parentId + // }; + // } if (this.config['geometry_type']) { postData['geometry'] = formValue['geometry']; diff --git a/frontend/app/components/breadcrumbs/breadcrumbs.component.ts b/frontend/app/components/breadcrumbs/breadcrumbs.component.ts index 854c824b7..f04da177c 100644 --- a/frontend/app/components/breadcrumbs/breadcrumbs.component.ts +++ b/frontend/app/components/breadcrumbs/breadcrumbs.component.ts @@ -43,9 +43,9 @@ export class BreadcrumbsComponent implements OnInit { ngOnInit() { if (this.obj === undefined) { - this._objectService.currentDataBreadCrumb.subscribe( - (breadCrumb) => (this.breadcrumbs = breadCrumb) - ); + this._objectService.currentDataBreadCrumb.subscribe((breadCrumb) => { + this.breadcrumbs = breadCrumb; + }); return; } } diff --git a/frontend/app/components/modules/modules.component.html b/frontend/app/components/modules/modules.component.html index 41758c685..0a1a1197b 100644 --- a/frontend/app/components/modules/modules.component.html +++ b/frontend/app/components/modules/modules.component.html @@ -25,7 +25,7 @@

{{ titleModule }}

color="primary" [ngClass]="{ isDisableBtn: !canAccessSite }" [disabled]="!canAccessSite" - [routerLink]="'sites_group'" + [routerLink]="'object/generic/sites_group'" *ngIf="currentUser" > Accès aux sites 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 e1a9ef075..a03551862 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 @@ -132,7 +132,7 @@

Attention

label="Ajouter une visite" [iconOrButton]="icon" [item]="row" - (onDeployed)="addChildren(row)" + (onDeployed)="addChildrenVisit(row)" (onSaved)="saveOptionChild($event)" > 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 3de9211ba..d2f27e41b 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 @@ -49,7 +49,7 @@ export class MonitoringDatatableGComponent implements OnInit { @Input() rowStatus: Array; @Output() rowStatusChange = new EventEmitter(); - @Output() addFromTable = new EventEmitter(); + @Output() addVisitFromTable = new EventEmitter(); @Output() saveOptionChildren = new EventEmitter(); @Output() bEditChanged = new EventEmitter(); @Input() currentUser; @@ -59,13 +59,16 @@ export class MonitoringDatatableGComponent implements OnInit { @Output() onFilter = new EventEmitter(); @Output() onSetPage = new EventEmitter(); @Output() onDetailsRow = new EventEmitter(); - @Output() addEvent = new EventEmitter(); @Output() tabChanged = new EventEmitter(); @Output() onDeleteEvent = new EventEmitter(); @Output() onEditEvent = new EventEmitter(); + @Output() onAddChildren = new EventEmitter(); + @Output() onAddObj = new EventEmitter(); @Input() bDeleteModalEmitter: EventEmitter; + @Input() parentPath: string; + bDeleteModal: boolean = false; bDeleteSpinner: boolean = false; @@ -215,10 +218,6 @@ export class MonitoringDatatableGComponent implements OnInit { } } - addChildren(selected) { - this.addFromTable.emit({ rowSelected: selected, objectType: this.activetabType }); - } - saveOptionChild($event: SelectObject) { this.saveOptionChildren.emit($event); } @@ -345,33 +344,20 @@ export class MonitoringDatatableGComponent implements OnInit { this.initPermissionAction(); } } + + addChildrenVisit(selected) { + this.addVisitFromTable.emit({ rowSelected: selected, objectType: this.activetabType }); + } + navigateToAddChildren(_, row) { - this.addEvent.emit(row); this._objService.changeObjectType(this.dataTableArray[this.activetabIndex]); - if (row && this.dataTableArray.length == 1) { - row['id'] = row[row.pk]; - this.router.navigate([row.id, 'create'], { - relativeTo: this._Activatedroute, - }); - } + row['object_type'] = this.dataTableArray[this.activetabIndex]['childType']; + this.onAddChildren.emit(row); } navigateToAddObj() { this._objService.changeObjectType(this.dataTableArray[this.activetabIndex]); - if (this.dataTableArray.length == 1) { - this.router.navigate(['create'], { - relativeTo: this._Activatedroute, - }); - } else { - this.router.navigate([ - 'monitorings', - this.dataTableArray[this.activetabIndex].routeBase, - 'create', - ]); - } - - // TODO: gérer la gestion de l'ajout (et ajout d'objet enfant) d'objet de type "site" depuis la page d'accueil de visualisation de groupe de site/ site - // + this.onAddObj.emit(this.dataTableArray[this.activetabIndex]['objectType']); } navigateToDetail(row) { @@ -404,42 +390,4 @@ export class MonitoringDatatableGComponent implements OnInit { this.rowSelected['name_object'] = row[varNameObjet]; this.bDeleteModal = true; } - - // TODO: Comprendre le fonctionnement de ObjectStatuts et RowsStatus - // initObjectsStatus() { - // const objectsStatus = {}; - // for (const childrenType of Object.keys(this.obj.children)) { - // objectsStatus[childrenType] = this.obj.children[childrenType].map( - // (child) => { - // return { - // id: child.id, - // selected: false, - // visible: true, - // current: false, - // }; - // } - // ); - // } - - // // init site status - // if (this.obj.siteId) { - // objectsStatus["site"] = []; - // this.sites["features"].forEach((f) => { - // // determination du site courrant - // let cur = false; - // if (f.properties.id_base_site == this.obj.siteId) { - // cur = true; - // } - - // objectsStatus["site"].push({ - // id: f.properties.id_base_site, - // selected: false, - // visible: true, - // current: cur, - // }); - // }); - // } - - // this.objectsStatus = objectsStatus; - // } } diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.css b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.css deleted file mode 100644 index 18d916f88..000000000 --- a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.css +++ /dev/null @@ -1,56 +0,0 @@ -:host ::ng-deep .obj-form { - margin: 0; - margin-bottom: 10px; - padding: 0; -} - -.hide-spinner { - display: none; -} - -.btn-height { - height: 39px; -} - -.float-right { - margin-left: 5px; -} - -.float-left { - margin-right: 10px; - float: left; -} - -form:invalid { - outline: none; -} - -form.ng-invalid { - border: 0px !important; -} - -.form-scroll-info-geom { - overflow-y: auto; - max-height: 60vh; -} - -.form-scroll { - overflow-y: auto; - max-height: 70vh; -} - -.btn-child { - border: 0px solid #202020; - padding-top: 2px; - padding-bottom: auto; - -webkit-box-shadow: 0px -2px 2px rgba(50, 50, 50, 0.3); - -moz-box-shadow: 0px -2px 2px rgba(50, 50, 50, 0.3); - box-shadow: 0px -2px 2px rgba(50, 50, 50, 0.3); - overflow: hidden; - height: fit-content; -} - -button:disabled { - cursor: not-allowed; - pointer-events: all !important; -} diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.html b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.html deleted file mode 100644 index 349bbd92a..000000000 --- a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.html +++ /dev/null @@ -1,167 +0,0 @@ - -

Attention

-

- - Vous êtes sur le point de supprimer {{obj.config["label"]}} : - {{obj.properties[obj.config["description_field_name"]]}} -
(id :{{obj.properties[obj.config["id_field_name"]]}}) -

- - -
- -
-
- - - - - - - - - - - -
- -

- Veuillez saisir une géométrie sur la carte -

-

- - La géométrie de groupe site est actuellement auto-générée sur la base des sites enfants - (si existants). Vous avez la possibilité de créer vous même une géométrie - -

- - -
- - - - - - - error La suppression de types de site entraine la - réinitialisation des champs associés - - - - -
- -
- - - - - - - - -
-
-
-
-
-
diff --git a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.spec.ts b/frontend/app/components/monitoring-form-g/monitoring-form.component-g.spec.ts deleted file mode 100644 index f3bc4dd70..000000000 --- a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { MonitoringFormComponent } from './monitoring-form.component'; -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; - -describe('MonitoringFormComponent', () => { - let component: MonitoringFormComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [MonitoringFormComponent], - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(MonitoringFormComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); 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 deleted file mode 100644 index 4d9c7e610..000000000 --- a/frontend/app/components/monitoring-form-g/monitoring-form.component-g.ts +++ /dev/null @@ -1,773 +0,0 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { - tap, - mergeMap, - map, - take, - switchMap, - concatMap, - takeUntil, - distinctUntilChanged, -} from 'rxjs/operators'; -import { ActivatedRoute } from '@angular/router'; -import { Router } from '@angular/router'; -import { DynamicFormService } from '@geonature_common/form/dynamic-form-generator/dynamic-form.service'; -import { CommonService } from '@geonature_common/service/common.service'; - -import { IDataForm } from '../../interfaces/form'; -import { ApiGeomService } from '../../services/api-geom.service'; -import { ConfigJsonService } from '../../services/config-json.service'; -import { FormService } from '../../services/form.service'; -import { IExtraForm } from '../../interfaces/object'; -import { JsonData } from '../../types/jsondata'; -import { Observable, ReplaySubject, Subject, of } from 'rxjs'; -import { TOOLTIPMESSAGEALERT } from '../../constants/guard'; -import { GeoJSONService } from '../../services/geojson.service'; - -@Component({ - selector: 'pnx-monitoring-form-g', - templateUrl: './monitoring-form.component-g.html', - styleUrls: ['./monitoring-form.component-g.css'], -}) -export class MonitoringFormComponentG implements OnInit { - @Input() currentUser; - - @Input() objForm: { - static: FormGroup; - dynamic?: FormGroup; - }; - // @Input() objForm: FormGroup; - objFormStatic: FormGroup; - objFormDynamic: FormGroup; - - // @Input() obj: any; - @Output() objChanged = new EventEmitter(); - - @Input() objectsStatus; - @Output() objectsStatusChange = new EventEmitter(); - - @Input() bEdit: boolean; - @Output() bEditChange = new EventEmitter(); - - @Input() sites: {}; - @Input() apiService: ApiGeomService; - @Input() isExtraForm: boolean = false; - - extraFormCtrl: IExtraForm; - geomCtrl: { frmCtrl: FormControl; frmName: string }; - dataForm: IDataForm; - searchSite = ''; - - isExtraControlChange: boolean; - isUndefinedChange: boolean; - obj: JsonData; - objFormsDefinition: { - static: JsonData[]; - dynamic?: JsonData[]; - }; - - objFormGroups: FormGroup; - prop: JsonData; - specificForm$: Observable; - createSpecificForm$: Observable; - meta: {}; - private destroyed$: ReplaySubject = new ReplaySubject(1); - - public bSaveSpinner = false; - public bSaveAndAddChildrenSpinner = false; - public bDeleteSpinner = false; - public bDeleteModal = false; - public bChainInput = false; - public bAddChildren = false; - public chainShow = []; - public queryParams = {}; - - canDelete: boolean = false; - canUpdate: boolean = false; - canCreateOrUpdate: boolean = false; - geomCalculated: boolean = false; - - toolTipNotAllowed: string = TOOLTIPMESSAGEALERT; - constructor( - private _formBuilder: FormBuilder, - private _route: ActivatedRoute, - private _configService: ConfigJsonService, - private _commonService: CommonService, - private _dynformService: DynamicFormService, - private _formService: FormService, - private _router: Router, - private _geojsonService: GeoJSONService - ) {} - - ngOnInit() { - if (!this.objFormStatic) { - this.objFormStatic = this._formBuilder.group({}); - } - if (!this.objFormDynamic && this.isExtraForm) { - this.objFormDynamic = this._formBuilder.group({}); - } - this.isExtraForm - ? (this.objForm = { static: this.objFormStatic, dynamic: this.objFormDynamic }) - : (this.objForm = { static: this.objFormStatic }); - this.isExtraForm - ? (this.objFormsDefinition = { static: [{}], dynamic: [{}] }) - : (this.objFormsDefinition = { static: [{}] }); - - this.specificForm$ = this._formService.currentDataSpec.pipe( - mergeMap((newObj) => { - return this.apiService.getConfig().pipe( - map((prop) => { - this.prop = prop; - return { newObj, prop: prop }; - }) - ); - }) - ); - - this.createSpecificForm$ = this._formService.currentDataSpecToCreate.pipe( - mergeMap((specConfig) => { - return this.apiService.getConfig().pipe( - map((prop) => { - this.prop = prop; - return { specConfig: specConfig, prop: prop }; - }) - ); - }) - ); - this._formService.currentData - .pipe( - distinctUntilChanged((prev, curr) => prev['pk'] === curr['pk']), - takeUntil(this.destroyed$), - tap((data) => { - this.obj = data; - this.obj.id = this.obj[this.obj.pk]; - this.initPermission(); - // this.bEdit ? this._geojsonService.setCurrentmapData(this.obj.geometry):null; - // this.bEdit && this._geojsonService.currentLayer == null ? (this._geojsonService.removeAllFeatureGroup(),this._geojsonService.setCurrentmapData(this.obj.geometry)) : null; - }), - concatMap((data: any) => this._configService.init(data.moduleCode)), - concatMap((data) => { - return this.apiService.getConfig().pipe( - map((prop) => { - this.prop = prop; - return { prop: prop }; - }) - ); - }), - switchMap(({ prop }) => { - if (this.isExtraForm) { - return this._formService.currentExtraFormCtrl.pipe( - map((frmCtrl) => { - return { prop: prop, frmCtrl: frmCtrl }; - }) - ); - } else { - return of({ prop: prop }); - } - }) - ) - .subscribe((data) => { - this.initObj(data.prop); - this.obj.config = this._configService.configModuleObject( - this.obj.moduleCode, - this.obj.objectType - ); - const schema = this._configService.schema(this.obj.moduleCode, this.obj.objectType); - this.obj[this.obj.moduleCode] = schema; - this.obj.specific == undefined ? (this.obj.specific = {}) : null; - this.obj.bIsInitialized = true; - - this.queryParams = this._route.snapshot.queryParams || {}; - this.bChainInput = this._configService.frontendParams().bChainInput; - // meta pour les parametres dynamiques - // ici pour avoir acces aux nomenclatures - this.meta = { - // nomenclatures: this._dataUtilsService.getDataUtil('nomenclature'), - // dataset: this._dataUtilsService.getDataUtil('dataset'), - id_role: this.currentUser.id_role, - bChainInput: this.bChainInput, - parents: this.obj.parents, - }; - - Object.keys(this.objFormsDefinition).forEach((key) => { - let configType: string; - key == 'static' ? (configType = 'generic') : (configType = 'specific'); - - this.obj.config - ? (this.objFormsDefinition[key] = this._dynformService - .formDefinitionsdictToArray(this.obj[configType], this.meta) - .filter((formDef) => formDef.type_widget) - .sort((a, b) => { - // medias à la fin - return a.attribut_name === 'medias' ? +1 : b.attribut_name === 'medias' ? -1 : 0; - })) - : null; - }); - - // display_form pour customiser l'ordre dans le formulaire - // les éléments de display form sont placé en haut dans l'ordre du tableau - // tous les éléments non cachés restent affichés - - let displayProperties = [ - ...(this._configService.configModuleObjectParam( - this.obj.moduleCode, - this.obj.objectType, - 'display_properties' - ) || []), - ]; - if (displayProperties && displayProperties.length) { - displayProperties.reverse(); - Object.keys(this.objFormsDefinition).forEach((key) => { - this.objFormsDefinition[key].sort((a, b) => { - let indexA = displayProperties.findIndex((e) => e == a.attribut_name); - let indexB = displayProperties.findIndex((e) => e == b.attribut_name); - return indexB - indexA; - }); - }); - } - this.objForm.static.addControl('patch_update', this._formBuilder.control(0)); - - this.isExtraForm ? this.addExtraFormCtrl(data['frmCtrl']) : null; - // set geometry - if (this.obj.config && this.obj.config['geometry_type']) { - const validatorRequired = - this.obj.objectType == 'sites_group' - ? this._formBuilder.control('') - : this._formBuilder.control('', Validators.required); - let frmCtrlGeom = { - frmCtrl: validatorRequired, - frmName: 'geometry', - }; - this.addGeomFormCtrl(frmCtrlGeom); - } - this.initForm(); - this.isExtraForm && this.bEdit ? this.updateSpecificForm() : null; - this.isExtraForm && !this.bEdit ? this.createSpecificForm() : null; - }); - this.geomCalculated = this.obj.hasOwnProperty('is_geom_from_child') - ? this.obj.is_geom_from_child - : false; - this.geomCalculated || this.obj.id == undefined ? (this.obj.geometry = null) : null; - this.bEdit - ? (this._geojsonService.removeAllFeatureGroup(), - this._geojsonService.setCurrentmapData(this.obj.geometry, this.geomCalculated)) - : null; - } - - /** pour réutiliser des paramètres déjà saisis */ - keepDefinitions() { - return Object.keys(this.objFormsDefinition).forEach((key) => { - this.objFormsDefinition[key].filter((def) => - this._configService - .configModuleObjectParam(this.obj.moduleCode, this.obj.objectType, 'keep') - .includes(def.attribut_name) - ); - }); - } - - setQueryParams() { - // par le biais des parametre query de route on donne l'id du ou des parents - // permet d'avoir un 'tree' ou un objet est sur plusieurs branches - // on attend des ids d'où test avec parseInt - for (const key of Object.keys(this.queryParams)) { - const strToInt = parseInt(this.queryParams[key]); - if (!Number.isNaN(strToInt)) { - this.obj.properties[key] = strToInt; - } - } - } - - /** initialise le formulaire quand le formulaire est prêt ou l'object est prêt */ - - initForm() { - if (!(this.objForm.static && this.obj.bIsInitialized && this.obj.config)) { - return; - } - - this.setQueryParams(); - - this._formService.formValues(this.obj).subscribe((formValue) => { - const allKeysForm = Object.keys(formValue); - const allKeysStatic = Object.keys(this.obj.config.generic); - if (this.obj.config['geometry_type'] && allKeysForm.includes('geometry')) { - allKeysStatic.push('geometry'); - } - // const allKeysSpecific = Object.keys(this.obj.specific); - let formValueStatic = {}; - for (let key of allKeysForm) { - if (allKeysStatic.includes(key)) { - formValueStatic[key] = formValue[key]; - } - } - this.objForm.static.patchValue(formValueStatic); - this._formService.changeFormMapObj({ - frmGp: this.objForm.static, - bEdit: true, - obj: this.obj, - }); - this.setDefaultFormValue(); - }); - } - - initValueFormDynamic() { - if (!(this.objForm.dynamic && this.obj.bIsInitialized && this.obj.config)) { - return; - } - - this.setQueryParams(); - this._formService.formValues(this.obj).subscribe((formValue) => { - const allKeysForm = Object.keys(formValue); - const allKeysSpecific = Object.keys(this.obj.specific); - let formValueSpecific = {}; - for (let key of allKeysForm) { - if (allKeysSpecific.includes(key) || key == 'types_site') { - formValueSpecific[key] = formValue[key]; - } - } - this.objForm.dynamic.patchValue(formValueSpecific); - this.setDefaultFormValue(); - // this.dataForm = propertiesValues; - }); - } - - keepNames() { - return ( - this._configService.configModuleObjectParam( - this.obj.moduleCode, - this.obj.objectType, - 'keep' - ) || [] - ); - } - - idFieldName() { - return this._configService.configModuleObjectParam( - this.obj.moduleCode, - this.obj.objectType, - 'id_field_Name' - ); - } - - resetObjForm() { - //NEW- setResolvedProperties - - // quand on enchaine les relevés - // const chainShow = this.obj.configParam('chain_show'); - - //TODO: Ici chain_show est présent que dans le fichier de config visit.json - // --> voir à quoi correspond ce chainShow où on utilise les propriétés (id_base_site, num_passage etc) - const chainShow = this._configService.configModuleObjectParam( - this.obj.moduleCode, - this.obj.objectType, - 'chain_show' - ); - if (chainShow) { - this.chainShow.push(chainShow.map((key) => this.obj.resolvedProperties[key])); - this.chainShow.push(this.obj.resolvedProperties); - } - - // les valeur que l'on garde d'une saisie à l'autre - const keep = {}; - for (const key of this.keepNames()) { - keep[key] = this.obj.properties[key]; - } - - this.obj = { - bIsInitialized: false, - moduleCode: this.obj.moduleCode, - objectType: this.obj.objectType, - endPoint: this.obj.endPoint, - properties: {}, - generic: this.obj.generic, - }; - this.obj.config = this._configService.configModuleObject( - this.obj.moduleCode, - this.obj.objectType - ); - this.obj.properties[this.idFieldName()] = null; - - // pq get ????? - // this.obj.get(0).subscribe(() => { - this.obj.bIsInitialized = true; - for (const key of this.keepNames()) { - this.obj.properties[key] = keep[key]; - } - - this.objChanged.emit(this.obj); - this.objForm.static.patchValue({ geometry: null }); - this.objForm.dynamic?.patchValue({}); - this.initForm(); - this.isExtraForm ? this.initValueFormDynamic() : null; - // }; - } - - /** Pour donner des valeurs par defaut si la valeur n'est pas définie - * id_digitiser => current_user.id_role - * id_inventor => current_user.id_role - * date => today - */ - setDefaultFormValue() { - const value = this.objForm.static.value; - const date = new Date(); - const defaultValue = { - id_digitiser: value['id_digitiser'] || this.currentUser.id_role, - id_inventor: value['id_inventor'] || this.currentUser.id_role, - first_use_date: value['first_use_date'] || { - year: date.getUTCFullYear(), - month: date.getUTCMonth() + 1, - day: date.getUTCDate(), - }, - }; - this.objForm.static.patchValue(defaultValue); - } - - /** - * TODO faire des fonctions dans monitoring objet (ou moniotring objet service pour naviguer - */ - - /** - * Valider et renseigner les enfants - */ - navigateToAddChildren() { - this.bEditChange.emit(false); - this.obj.navigateToAddChildren(); - } - - /** - * Valider et aller à la page de l'objet - */ - navigateToDetail(id, objectType, queryParams) { - // patch bug navigation - // 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 = - this.obj.urlRelative == '/monitorings' - ? [this.apiService.objectObs.routeBase, id] - : [objectType, id].filter((s) => !!s); - const urlPathDetail = [this.obj.urlRelative].concat(urlSegment).join('/'); - this.objChanged.emit(this.obj); - const urlRelative = this.obj.urlRelative ? true : false; - if (urlRelative) { - this._router.navigateByUrl(urlPathDetail); - } else { - const urlTree = this._router.parseUrl(this._router.url); - const urlWithoutParams = urlTree.root.children['primary'].segments - .map((it) => it.path) - .join('/'); - this._router.navigate([urlWithoutParams]); - } - this.bEditChange.emit(false); - } - - /** - * Valider et aller à la page de l'objet - */ - navigateToParent() { - // FIXME:: voir erreur de redirection (comparaison avec branche où ça fonctionnait ?) - this.bEditChange.emit(false); // patch bug navigation - if (!this.bEdit) { - this._router.navigate(['..'], { relativeTo: this._route }); - } - } - - navigateToParentAfterDelete() { - this.bEditChange.emit(false); // patch bug navigation - if (this.obj.objectType == 'site' && this._router.url.includes('sites_group')) { - this._router.navigate(['monitorings', 'sites_group', this._route.parent.snapshot.params.id]); - } else { - this._router.navigate(['..'], { relativeTo: this._route }); - } - } - - msgToaster(action) { - // return `${action} ${this.obj.labelDu()} ${this.obj.description()} effectuée`.trim(); - return `${action} effectuée`.trim(); - } - - /** TODO améliorer site etc.. */ - onSubmit(isAddChildrend = false) { - isAddChildrend - ? (this.bSaveAndAddChildrenSpinner = this.bAddChildren = true) - : (this.bSaveSpinner = true); - const { patch_update, ...sendValue } = this.dataForm; - const objToUpdateOrCreate = this._formService.postData(sendValue, this.obj); - const action = this.obj.id - ? this.apiService.patch(this.obj.id, objToUpdateOrCreate) - : this.apiService.create(objToUpdateOrCreate); - const actionLabel = this.obj.id ? 'Modification' : 'Création'; - action.subscribe((objData) => { - this._commonService.regularToaster('success', this.msgToaster(actionLabel)); - this.bSaveSpinner = this.bSaveAndAddChildrenSpinner = false; - - Object.entries(objData['properties']).forEach(([key, value]) => { - this.obj['properties'][key] = value; - }); - - 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') { - this._configService.loadConfig(this.obj.moduleCode).subscribe(); - } - - if (this.bChainInput) { - this.resetObjForm(); - } else if (this.bAddChildren) { - this.navigateToAddChildren(); - } else { - if ( - this._configService.configModuleObjectParam( - this.obj.moduleCode, - this.obj.objectType, - 'redirect_to_parent' - ) - ) { - this.navigateToParent(); - } else { - this.navigateToDetail(this.obj.id, this.obj.objectType, this.queryParams); - } - } - }); - } - - onCancelEdit() { - if (this.bEdit) { - const urlTree = this._router.parseUrl(this._router.url); - const urlWithoutParams = urlTree.root.children['primary'].segments - .map((it) => it.path) - .join('/'); - this._router.navigate([urlWithoutParams]); - - this._geojsonService.removeAllFeatureGroup(); - this.obj.geometry == null - ? this._geojsonService.setMapDataWithFeatureGroup([this._geojsonService.sitesFeatureGroup]) - : this._geojsonService.setMapBeforeEdit(this.obj.geometry); - this.bEditChange.emit(false); - } else { - this.navigateToParent(); - } - } - - onDelete() { - this.bDeleteSpinner = true; - // : this.obj.post(this.objForm.value); - this.apiService.delete(this.obj.id).subscribe((del) => { - this.bDeleteSpinner = this.bDeleteModal = false; - this.objChanged.emit('deleted'); - setTimeout(() => { - this._commonService.regularToaster('info', this.msgToaster('Suppression')); - this.navigateToParentAfterDelete(); - }, 100); - }); - } - - onObjFormValueChange(event) { - // let {id_module,medias, ...rest} = this.objForm.value; - // this.dataForm = rest - this.dataForm = { ...this.objForm.static.value, ...this.objForm.dynamic?.value }; - const change = this._configService.change(this.obj.moduleCode, this.obj.objectType); - // if('geometry' in this.objForm.controls){ - // this._formService.changeFormMapObj({frmGp:this.objForm,bEdit:true, obj: this.obj}) - // } - - if (!change) { - return; - } - setTimeout(() => { - change({ objForm: this.objForm.static, meta: this.meta }); - }, 100); - } - - onObjFormDynamicValueChange(event) { - // let {id_module,medias, ...rest} = this.objForm.value; - // this.dataForm = rest - this.dataForm = { ...this.objForm.static.value, ...this.objForm.dynamic.value }; - const change = this._configService.change(this.obj.moduleCode, this.obj.objectType); - // if('geometry' in this.objForm.controls){ - // this._formService.changeFormMapObj({frmGp:this.objForm,bEdit:true, obj: this.obj}) - // } - if (this.extraFormCtrl && !this.extraFormCtrl.frmCtrl.valid) { - this.extraFormCtrl.frmCtrl.markAllAsTouched(); - } - if (!change) { - return; - } - setTimeout(() => { - change({ objForm: this.objForm.static, meta: this.meta }); - }, 100); - } - - procesPatchUpdateForm() { - Object.keys(this.objForm).forEach((form) => - this.objForm[form].patchValue({ - patch_update: this.objForm[form].value.patch_update + 1, - }) - ); - } - - /** bChainInput gardé dans config service */ - bChainInputChanged() { - for (const formDef of this.objFormsDefinition.static) { - formDef.meta.bChainInput = this.bChainInput; - } - this._configService.setFrontendParams('bChainInput', this.bChainInput); - // patch pour recalculers - this.procesPatchUpdateForm(); - } - - addExtraFormCtrl(frmCtrl: IExtraForm) { - if (frmCtrl.frmName in this.objFormDynamic.controls) { - } else { - this.objForm.dynamic.addControl(frmCtrl.frmName, frmCtrl.frmCtrl); - } - - this.extraFormCtrl = frmCtrl; - } - - addGeomFormCtrl(frmCtrl: { frmCtrl: FormControl; frmName: string }) { - if (frmCtrl.frmName in this.objForm.static.controls) { - } else { - this.objForm.static.addControl(frmCtrl.frmName, frmCtrl.frmCtrl); - } - this.geomCtrl = frmCtrl; - } - - getConfigFromBtnSelect(configSpec) { - // TODO: Ajout de tous les id_parents ["id_sites_groups" etc ] dans l'objet obj.dataComplement - // Check if specific and dataComplement already exist - this.obj.specific = {}; - this.obj.dataComplement = {}; - - Object.entries(configSpec).forEach(([key, value]) => { - if (this.obj.dataComplement[key] && key != 'types_site') { - return; - } - if (configSpec[key].config != undefined) { - if (Object.keys(configSpec[key].config).length !== 0) { - Object.assign(this.obj.specific, configSpec[key].config.specific); - if ('keep' in configSpec[key].config) { - this.obj.config.keep ? null : (this.obj.config.keep = []); - !this.obj.config.keep.includes(configSpec[key].config.keep) - ? this.obj.config.keep.push(...configSpec[key].config.keep) - : null; - } - } - this.obj.dataComplement[key] = value; - } else { - this.obj.dataComplement[key] ? null : (this.obj.dataComplement[key] = []); - this.obj.dataComplement[key] = configSpec[key]; - } - }); - } - - initObj(prop) { - this.obj['properties'] = prop; - Object.entries(this.obj).forEach(([key, value]) => { - if (key != 'properties' && key in this.obj['properties']) { - this.obj['properties'][key] = value; - } - }); - this.obj.resolvedProperties = this._configService.setResolvedProperties(this.obj); - } - - updateExtraFormOnly() { - if (!(this.objForm.dynamic && this.obj.bIsInitialized)) { - return; - } - // pour donner la valeur de l'objet au formulaire - this._formService.formValues(this.obj).subscribe((formValue) => { - const allKeysForm = Object.keys(formValue); - const allKeysGeneric = Object.keys(this.obj.config.generic); - const allKeysSpecific = Object.keys(this.obj.specific); - let formValueSpecific = {}; - for (let key of allKeysForm) { - if (allKeysSpecific.includes(key)) { - formValueSpecific[key] = formValue[key]; - } - } - this.objForm.dynamic.patchValue(formValueSpecific); - // this.setDefaultFormValue(); - // this.dataForm = propertiesValues; - // reset geom ? - }); - } - - createSpecificForm() { - this.createSpecificForm$.subscribe(({ specConfig, prop }) => { - this.obj.bIsInitialized = true; - this.obj.id = this.obj[this.obj.pk]; - this.getConfigFromBtnSelect(specConfig); - this.initObj(prop); - this.initElementFormDynamic(); - this.initValueFormDynamic(); - }); - } - updateSpecificForm() { - this.specificForm$.subscribe(({ newObj, prop }) => { - this.obj.bIsInitialized = true; - this.obj.id = this.obj[this.obj.pk]; - this.obj.dataComplement = newObj.newObj.dataComplement; - this.obj.specific = newObj.newObj.specific; - Object.assign(this.obj, newObj.propSpec); - this.initObj(prop); - this.initElementFormDynamic(); - this.initValueFormDynamic(); - }); - } - - initElementFormDynamic() { - const schema = this._configService.schema(this.obj.moduleCode, this.obj.objectType); - if (Object.keys(this.obj.specific).length !== 0) { - Object.assign(schema, this.obj.specific); - } - - this.obj[this.obj.moduleCode] = schema; - this.objFormsDefinition.dynamic = this._dynformService - .formDefinitionsdictToArray(this.obj.specific, this.meta) - .filter((formDef) => formDef.type_widget) - .sort((a, b) => { - // medias à la fin - return a.attribut_name === 'medias' ? +1 : b.attribut_name === 'medias' ? -1 : 0; - }); - } - - initPermission() { - !this.bEdit - ? (this.canCreateOrUpdate = true) - : ((this.canDelete = this.obj.cruved['D']), - (this.canCreateOrUpdate = this.canUpdate = this.obj.cruved['U'])); - } - - notAllowedMessage() { - this._commonService.translateToaster( - 'warning', - "Vous n'avez pas les permissions nécessaires pour éditer l'objet" - ); - } - - ngOnDestroy() { - this._formService.changeFormMapObj({ - frmGp: this._formBuilder.group({}), - bEdit: false, - obj: {}, - }); - this.obj = {}; - this._formService.createSpecificForm({}); - this.destroyed$.next(true); - this.destroyed$.complete(); - } - - isEmptyObject(obj) { - return obj && Object.keys(obj).length === 0; - } -} diff --git a/frontend/app/components/monitoring-form/monitoring-form.component.html b/frontend/app/components/monitoring-form/monitoring-form.component.html index ccdcec562..f7997893c 100644 --- a/frontend/app/components/monitoring-form/monitoring-form.component.html +++ b/frontend/app/components/monitoring-form/monitoring-form.component.html @@ -89,23 +89,30 @@

Attention

(myFormGroupChange)="initForm()" (change)="onObjFormValueChange($event)" > - - - + + + + +

Champs associés au type: {{obj.config['types_site'][item.key].name}}

+ +
+
+
- - - +
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 82b841bcd..3cc3743d3 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,7 +1,8 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; +import { mergeMap, concatMap, tap } from 'rxjs/operators'; import { endPoints } from '../../enum/endpoints'; import { ISite, ISiteType } from '../../interfaces/geom'; @@ -15,7 +16,10 @@ import { IBreadCrumb } from '../../interfaces/object'; import { breadCrumbElementBase } from '../breadcrumbs/breadcrumbs.component'; import { GeoJSONService } from '../../services/geojson.service'; import { AuthService, User } from '@geonature/components/auth/auth.service'; -import { concatMap, tap } from 'rxjs/operators'; + +import { MonitoringObjectService } from '../../services/monitoring-object.service'; +import { ConfigService } from '../../services/config.service'; +import { MonitoringObject } from '../../class/monitoring-object'; @Component({ selector: 'monitoring-sites-create', @@ -24,7 +28,7 @@ import { concatMap, tap } from 'rxjs/operators'; }) export class MonitoringSitesCreateComponent implements OnInit { site: ISite; - form: FormGroup; + objForm: FormGroup; paramToFilt: string = 'label'; funcToFilt: Function; titleBtn: string = 'Choix des types de sites'; @@ -39,6 +43,8 @@ export class MonitoringSitesCreateComponent implements OnInit { breadCrumbElemnt: IBreadCrumb = { label: 'Groupe de site', description: '' }; breadCrumbElementBase: IBreadCrumb = breadCrumbElementBase; + obj: MonitoringObject; + bEdit: boolean = true; currentUser: User; constructor( private _auth: AuthService, @@ -46,81 +52,71 @@ export class MonitoringSitesCreateComponent implements OnInit { private _formBuilder: FormBuilder, private _sitesGroupService: SitesGroupService, public siteService: SitesService, - private route: ActivatedRoute, private _objService: ObjectService, - public geojsonService: GeoJSONService + public geojsonService: GeoJSONService, + private _monitoringObjServiceMonitoring: MonitoringObjectService, + protected _configService: ConfigService, + private _route: ActivatedRoute ) {} ngOnInit() { + this.bEdit = true; + this.objForm = this._formBuilder.group({}); + + const elements = document.getElementsByClassName('monitoring-map-container'); + if (elements.length >= 1) { + elements[0].remove(); + } + + this.obj = new MonitoringObject('generic', 'site', null, this._monitoringObjServiceMonitoring); this.currentUser = this._auth.getCurrentUser(); - this.route.parent.url + + this._route.paramMap .pipe( - tap((urlPath) => { - const urlParent = urlPath[urlPath.length - 1].path; - this.urlRelative = - urlParent == 'sites' - ? '/monitorings' - : this.removeLastPart(this.route.snapshot['_routerState'].url); + mergeMap(() => { + return this.initConfig(); }), - concatMap(() => { - return this.route.data; + mergeMap(() => { + return this.obj.get(0); }) ) - .subscribe(({ data }) => { - data ? (this.id_sites_group = data.id_sites_group) : (this.id_sites_group = null); - - 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: data ? data.objectType : {}, - }, - this.urlRelative - ); - this.form = this._formBuilder.group({}); - this.funcToFilt = this.partialfuncToFilt.bind(this); - data ? this.updateBreadCrumb(data) : null; + .subscribe((params) => { + this.obj.initTemplate(); + this._formService.changeFormMapObj({ + frmGp: this.objForm, + bEdit: true, + obj: this.obj, + }); + this.obj.bIsInitialized = true; }); } - removeLastPart(url: string): string { - return url.slice(0, url.lastIndexOf('/')); + onObjChanged(obj: MonitoringObject) { + this.obj = obj; } - partialfuncToFilt( - pageNumber: number, - limit: number, - valueToFilter: string - ): Observable> { - return this.siteService.getTypeSites(pageNumber, limit, { - label_fr: valueToFilter, - sort_dir: 'desc', - }); - } - - onSendConfig(config: JsonData): void { - this.config = this.addTypeSiteListIds(config); - this.createFormSpec(); - } - - 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']); + initConfig(): Observable { + return this._configService.init().pipe( + concatMap(() => { + if (this.obj.objectType == 'site' && this.obj.id != null) { + return this._monitoringObjServiceMonitoring + .configService() + .loadConfigSpecificConfig(this.obj) + .pipe( + tap((config) => { + this.obj.template_specific = this._monitoringObjServiceMonitoring + .configService() + .addSpecificConfig(config); + }) + ); + } else { + return of(null); } - } - } - return config; - } - - createFormSpec() { - this._formService.createSpecificForm(this.config); + }), + mergeMap(() => { + return of(true); + }) + ); } updateBreadCrumb(sitesGroup) { diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.css b/frontend/app/components/monitoring-sites-detail/monitoring-sites-detail.component.css similarity index 100% rename from frontend/app/components/monitoring-sites/monitoring-sites.component.css rename to frontend/app/components/monitoring-sites-detail/monitoring-sites-detail.component.css diff --git a/frontend/app/components/monitoring-visits/monitoring-visits.component.html b/frontend/app/components/monitoring-sites-detail/monitoring-sites-detail.component.html similarity index 79% rename from frontend/app/components/monitoring-visits/monitoring-visits.component.html rename to frontend/app/components/monitoring-sites-detail/monitoring-sites-detail.component.html index 2bd9e137c..268892db8 100644 --- a/frontend/app/components/monitoring-visits/monitoring-visits.component.html +++ b/frontend/app/components/monitoring-sites-detail/monitoring-sites-detail.component.html @@ -8,28 +8,15 @@ > {{ site.base_site_name }} - - - +> + { + this.initSiteVisit(); + }); } initSiteVisit() { + // Get obj data const $getPermissionMonitoring = this._objServiceMonitoring.getCruvedMonitoring(); const $permissionUserObject = this._permissionService.currentPermissionObj; $getPermissionMonitoring @@ -126,6 +131,14 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement this._Activatedroute.params.pipe( map((params) => { this.checkEditParam = params['edit']; + this.parentsPath = + this._Activatedroute.snapshot.queryParamMap.getAll('parents_path') || []; + this.obj = new MonitoringObject( + 'generic', + 'site', + params['id'], + this._monitoringObjServiceMonitoring + ); return params['id'] as number; }), tap((id: number) => { @@ -154,6 +167,7 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement return forkJoin({ objObsSite: this.siteService.initConfig(), objObsVisit: this._visits_service.initConfig(), + obj: this.obj.get(0), }).pipe( tap((objConfig) => (this.objParent = objConfig.objObsSite)), map((objConfig) => { @@ -175,7 +189,10 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement ); }), mergeMap((data) => { - if (isNaN(this.siteGroupIdParent)) { + if (this.parentsPath.includes('sites_group')) { + this.siteGroupIdParent = data.site.id_sites_group; + } + if (!this.siteGroupIdParent) { return of(data); } else { return iif( @@ -207,6 +224,7 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement count: data.visits.count, limit: data.visits.limit, }; + this.baseFilters = { id_base_site: this.site.id_base_site }; this.colsname = data.objConfig.objObsVisit.dataTable.colNameObj; let siteList = this.siteService.formatLabelTypesSite([this.site]); @@ -241,7 +259,7 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement onEachFeatureSite() { return (feature, layer) => { - const popup = this._popup.setSitePopup(feature); + const popup = this._popup.setSitePopup('generic', feature, {}); layer.bindPopup(popup); }; } @@ -261,9 +279,12 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement } seeDetails($event) { - this.router.navigate([ - `monitorings/object/${$event.module.module_code}/visit/${$event.id_base_visit}`, - ]); + this.router.navigate( + [`/monitorings/object/${$event.module.module_code}/visit/${$event.id_base_visit}`], + { + queryParams: { parents_path: ['module', 'site'] }, + } + ); } getModules() { @@ -280,9 +301,9 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement //create_object/cheveches_sites_group/visit?id_base_site=47 this._configService.init(moduleCode).subscribe(() => { const keys = Object.keys(this._configService.config()[moduleCode]); - const parent_paths = ['sites_group', 'site'].filter((item) => keys.includes(item)); + const parents_path = ['sites_group', 'site'].filter((item) => keys.includes(item)); this.router.navigate([`monitorings/create_object/${moduleCode}/visit`], { - queryParams: { id_base_site: this.site.id_base_site, parents_path: parent_paths }, + queryParams: { id_base_site: this.site.id_base_site, parents_path: parents_path }, }); }); } @@ -417,7 +438,7 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement this.breadCrumbChild['url'] = [ this.breadCrumbElementBase.url, this.breadCrumbParent.id?.toString(), - this.breadCrumbChild.objectType, + 'object/generic/site', this.breadCrumbChild.id?.toString(), ].join('/'); @@ -431,10 +452,9 @@ export class MonitoringVisitsComponent extends MonitoringGeomComponent implement this.breadCrumbChild.label = 'Site'; this.breadCrumbChild['id'] = sites.id_base_site; this.breadCrumbChild['objectType'] = this.siteService.objectObs.objectType + 's' || 'sites'; - this.breadCrumbChild['url'] = [ - this.breadCrumbChild.objectType, - this.breadCrumbChild.id?.toString(), - ].join('/'); + this.breadCrumbChild['url'] = ['object/generic/site', this.breadCrumbChild.id?.toString()].join( + '/' + ); this.breadCrumbList = [this.breadCrumbElementBase, this.breadCrumbChild]; this._objService.changeBreadCrumb(this.breadCrumbList, true); diff --git a/frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.html b/frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.html index c6f96978e..92d028bf0 100644 --- a/frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.html +++ b/frontend/app/components/monitoring-sitesgroups-create/monitoring-sitesgroups-create.component.html @@ -3,8 +3,6 @@ {{ sitesGroupService.objectObs.addObjLabel }}
- +
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 02ede36a6..f3c2b8cdb 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 @@ -2,12 +2,17 @@ import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { AuthService, User } from '@geonature/components/auth/auth.service'; +import { ActivatedRoute } from '@angular/router'; +import { mergeMap } from 'rxjs/operators'; import { endPoints } from '../../enum/endpoints'; import { ISitesGroup } from '../../interfaces/geom'; import { FormService } from '../../services/form.service'; import { SitesGroupService } from '../../services/api-geom.service'; import { ObjectService } from '../../services/object.service'; import { GeoJSONService } from '../../services/geojson.service'; +import { MonitoringObject } from '../../class/monitoring-object'; +import { MonitoringObjectService } from '../../services/monitoring-object.service'; +import { ConfigService } from '../../services/config.service'; @Component({ selector: 'monitoring-sitesgroups-create', @@ -19,31 +24,57 @@ export class MonitoringSitesGroupsCreateComponent implements OnInit { objForm: FormGroup; urlRelative: string; currentUser: User; + + obj: MonitoringObject; + bEdit: boolean = true; + constructor( private _auth: AuthService, private _formService: FormService, private _formBuilder: FormBuilder, private _objService: ObjectService, public sitesGroupService: SitesGroupService, - public geojsonService: GeoJSONService + public geojsonService: GeoJSONService, + private _monitoringObjServiceMonitoring: MonitoringObjectService, + private _configService: ConfigService, + private _route: ActivatedRoute ) {} ngOnInit() { - this.currentUser = this._auth.getCurrentUser(); - // Remove "create" segmentUrl - this.urlRelative = '/monitorings'; - this._formService.dataToCreate( - { - module: 'generic', - objectType: 'sites_group', - id: null, - endPoint: endPoints.sites_groups, - objSelected: {}, - }, - this.urlRelative - ); - this._objService.changeSelectedObj({}, true); + this.bEdit = true; this.objForm = this._formBuilder.group({}); + + const elements = document.getElementsByClassName('monitoring-map-container'); + if (elements.length >= 1) { + elements[0].remove(); + } + + this.obj = new MonitoringObject( + 'generic', + 'sites_group', + null, + this._monitoringObjServiceMonitoring + ); + this.currentUser = this._auth.getCurrentUser(); + + this._route.paramMap + .pipe( + mergeMap(() => { + return this._configService.init(); + }), + mergeMap(() => { + return this.obj.get(0); + }) + ) + .subscribe((params) => { + this.obj.initTemplate(); + this._formService.changeFormMapObj({ + frmGp: this.objForm, + bEdit: true, + obj: this.obj, + }); + this.obj.bIsInitialized = true; + }); } ngOnDestroy() { diff --git a/frontend/app/components/monitoring-visits/monitoring-visits.component.css b/frontend/app/components/monitoring-sitesgroups-detail/monitoring-sitesgroups-detail.component.css similarity index 100% rename from frontend/app/components/monitoring-visits/monitoring-visits.component.css rename to frontend/app/components/monitoring-sitesgroups-detail/monitoring-sitesgroups-detail.component.css diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.html b/frontend/app/components/monitoring-sitesgroups-detail/monitoring-sitesgroups-detail.component.html similarity index 75% rename from frontend/app/components/monitoring-sites/monitoring-sites.component.html rename to frontend/app/components/monitoring-sitesgroups-detail/monitoring-sitesgroups-detail.component.html index 71126a164..c5e9a0b13 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.html +++ b/frontend/app/components/monitoring-sitesgroups-detail/monitoring-sitesgroups-detail.component.html @@ -13,15 +13,9 @@ [permission]="currentPermission" >
- + + diff --git a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts b/frontend/app/components/monitoring-sitesgroups-detail/monitoring-sitesgroups-detail.component.ts similarity index 86% rename from frontend/app/components/monitoring-sites/monitoring-sites.component.ts rename to frontend/app/components/monitoring-sitesgroups-detail/monitoring-sitesgroups-detail.component.ts index 46fe02823..cd8c04b17 100644 --- a/frontend/app/components/monitoring-sites/monitoring-sites.component.ts +++ b/frontend/app/components/monitoring-sitesgroups-detail/monitoring-sitesgroups-detail.component.ts @@ -22,15 +22,20 @@ import { AuthService, User } from '@geonature/components/auth/auth.service'; import { DataMonitoringObjectService } from '../../services/data-monitoring-object.service'; import { TPermission } from '../../types/permission'; import { PermissionService } from '../../services/permission.service'; +import { MonitoringObject } from '../../class/monitoring-object'; +import { MonitoringObjectService } from '../../services/monitoring-object.service'; const LIMIT = 10; @Component({ - selector: 'monitoring-sites', - templateUrl: './monitoring-sites.component.html', - styleUrls: ['./monitoring-sites.component.css'], + selector: 'monitoring-sitesgroups-detail', + templateUrl: './monitoring-sitesgroups-detail.component.html', + styleUrls: ['./monitoring-sitesgroups-detail.component.css'], }) -export class MonitoringSitesComponent extends MonitoringGeomComponent implements OnInit { +export class MonitoringSitesgroupsDetailComponent + extends MonitoringGeomComponent + implements OnInit +{ siteGroupId: number; sites: ISite[]; sitesGroup: ISitesGroup; @@ -38,7 +43,7 @@ export class MonitoringSitesComponent extends MonitoringGeomComponent implements page: IPage; filters = {}; @Input() bEdit: boolean; - objForm: { static: FormGroup }; + form: FormGroup; objectType: IobjObs; objParent: any; breadCrumbElemnt: IBreadCrumb = { label: 'Groupe de site', description: '' }; @@ -61,6 +66,8 @@ export class MonitoringSitesComponent extends MonitoringGeomComponent implements currentUser: User; currentPermission: TPermission; + obj: MonitoringObject; + constructor( private _auth: AuthService, public _sitesGroupService: SitesGroupService, @@ -75,7 +82,8 @@ export class MonitoringSitesComponent extends MonitoringGeomComponent implements private _formService: FormService, private _dataMonitoringObjectService: DataMonitoringObjectService, private _permissionService: PermissionService, - private _popup: Popup + private _popup: Popup, + private _monitoringObjServiceMonitoring: MonitoringObjectService ) { super(); this.getAllItemsCallback = this.getSitesFromSiteGroupId; @@ -83,11 +91,12 @@ export class MonitoringSitesComponent extends MonitoringGeomComponent implements ngOnInit() { this.currentUser = this._auth.getCurrentUser(); - this.objForm = { static: this._formBuilder.group({}) }; - // this._sitesGroupService.init() + this.form = this._formBuilder.group({}); this._objService.changeObjectTypeParent(this._sitesGroupService.objectObs); this._objService.changeObjectType(this._siteService.objectObs); - this.initSite(); + this._configService.init().subscribe(() => { + this.initSite(); + }); } initSite() { @@ -107,6 +116,13 @@ export class MonitoringSitesComponent extends MonitoringGeomComponent implements this._Activatedroute.params.pipe( map((params) => { this.checkEditParam = params['edit']; + + this.obj = new MonitoringObject( + 'generic', + 'sites_group', + params['id'], + this._monitoringObjServiceMonitoring + ); return params['id'] as number; }), mergeMap((id: number) => { @@ -137,6 +153,7 @@ export class MonitoringSitesComponent extends MonitoringGeomComponent implements return forkJoin({ objObsSite: this._siteService.initConfig(), objObsSiteGp: this._sitesGroupService.initConfig(), + obj: this.obj.get(0), }).pipe( map((objObs) => { return { data, objectObs: objObs }; @@ -183,9 +200,10 @@ export class MonitoringSitesComponent extends MonitoringGeomComponent implements } onEachFeatureSite() { - const baseUrl = this.router.url + '/site'; return (feature, layer) => { - const popup = this._popup.setSitePopup(feature); + const popup = this._popup.setSitePopup('generic', feature, { + parents_path: ['module', 'sites_group'], + }); layer.bindPopup(popup); }; } @@ -209,16 +227,28 @@ export class MonitoringSitesComponent extends MonitoringGeomComponent implements seeDetails($event) { this._objService.changeSelectedParentObj($event); this._objService.changeObjectTypeParent(this._siteService.objectObs); - this.router.navigate([`site/${$event.id_base_site}`], { - relativeTo: this._Activatedroute, + this.router.navigate([`/monitorings/object/generic/site/${$event.id_base_site}`], { + queryParams: { parents_path: ['module', 'sites_group'] }, }); } editChild($event) { this._objService.changeSelectedParentObj($event); this._objService.changeObjectTypeParent(this._siteService.objectObs); - this.router.navigate([`site/${$event.id_base_site}`, { edit: true }], { - relativeTo: this._Activatedroute, + this.router.navigate([`/monitorings/object/generic/site/${$event.id_base_site}`], { + queryParams: { parents_path: ['module', 'sites_group'] }, + }); + } + + navigateToAddObj($event) { + const type = $event; + const queryParams = { + parents_path: ['module', 'sites_group'], + }; + + queryParams['id_sites_group'] = this.obj.id; + this.router.navigate(['/monitorings/object/generic/', type, 'create'], { + queryParams: queryParams, }); } @@ -304,6 +334,7 @@ export class MonitoringSitesComponent extends MonitoringGeomComponent implements onSaveAddChildren($event: SelectObject) { this.addNewVisit($event); } + getModules() { this._siteService .getSiteModules(this.siteSelectedId) @@ -323,9 +354,9 @@ export class MonitoringSitesComponent extends MonitoringGeomComponent implements this._configJsonService.init(this.modulSelected.id).subscribe(() => { const moduleCode = this.modulSelected.id; const keys = Object.keys(this._configJsonService.config()[moduleCode]); - const parent_paths = ['sites_group', 'site'].filter((item) => keys.includes(item)); + const parents_path = ['sites_group', 'site'].filter((item) => keys.includes(item)); this.router.navigate([`monitorings/create_object/${moduleCode}/visit`], { - queryParams: { id_base_site: this.siteSelectedId, parents_path: parent_paths }, + queryParams: { id_base_site: this.siteSelectedId, parents_path: parents_path }, }); }); } diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html index 1ee6dc740..1af827731 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.html @@ -12,15 +12,17 @@ [obj]="sitesGroups" (onDetailsRow)="seeDetails($event)" (onEditEvent)="editChild($event)" - (onDeleteEvent)="onDelete($event)" - (addEvent)="addSiteGpChild($event)" + (onDeleteEvent)="onDelete($event)" (tabChanged)="updateActiveTab($event)" [activetabIndex]="activetabIndex" - (addFromTable)="onAddChildren($event)" + (addVisitFromTable)="addChildrenVisit($event)" (saveOptionChildren)="onSaveAddChildren($event)" [bDeleteModalEmitter]="bDeleteModalEmitter" (rowStatusChange)="onSelectedOnDataTable($event)" + (onAddChildren)="navigateToAddChildren($event)" + (onAddObj)="navigateToAddObj($event)" [permission]="currentPermission" [currentUser]="currentUser" + parentPath="sites_group" > diff --git a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts index c3767b32b..5001712b5 100644 --- a/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts +++ b/frontend/app/components/monitoring-sitesgroups/monitoring-sitesgroups.component.ts @@ -101,12 +101,11 @@ export class MonitoringSitesGroupsComponent extends MonitoringGeomComponent impl limit: data.sitesGroups.data.limit, page: data.sitesGroups.data.page - 1, }; - this.sitesGroups = data.sitesGroups.data.items; // this.columns = [data.sitesGroups.data.items, data.sites.data.items] this.colsname = data.sitesGroups.objConfig.dataTable.colNameObj; this.currentRoute = data.route; - if (data.route == 'sites') { + if (data.route == 'site') { this.activetabIndex = 1; this.breadCrumbElementBase = breadCrumbBase.baseBreadCrumbSites.value; this.currentPermission.MONITORINGS_SITES.canRead ? this.getGeometriesSite() : null; @@ -131,13 +130,8 @@ export class MonitoringSitesGroupsComponent extends MonitoringGeomComponent impl } onEachFeatureSiteGroups(): Function { - const baseUrl = this.currentRoute; return (feature, layer) => { - const popup = this._popup.setPopup( - baseUrl + '/' + feature.properties.id_sites_group, - feature, - 'sites_group_name' - ); + const popup = this._popup.setSiteGroupPopup('generic', feature, {}); layer.bindPopup(popup); }; } @@ -190,21 +184,26 @@ export class MonitoringSitesGroupsComponent extends MonitoringGeomComponent impl } onEachFeatureSite() { - const baseUrl = 'monitorings/' + this.currentRoute; return (feature, layer) => { - const popup = this._popup.setSitePopup(feature); - + const popup = this._popup.setSitePopup('generic', feature, {}); layer.bindPopup(popup); }; } + seeDetails($event) { // TODO: routerLink + let objectType; if (this.activetabIndex == 1) { this._objService.changeObjectTypeParent(this._sitesService.objectObs); + objectType = "sites" } else { this._objService.changeObjectTypeParent(this._sites_group_service.objectObs); + objectType = "sites_group" + } - this.router.navigate(['monitorings', this.currentRoute, $event[$event.id]]); + this.router.navigate(['/monitorings/object/generic/', this.currentRoute, $event[$event.id]], { + queryParams: { parents_path: ['module', objectType] }, + }); } editChild($event) { @@ -219,7 +218,36 @@ export class MonitoringSitesGroupsComponent extends MonitoringGeomComponent impl this._sites_group_service.objectObs.objectType, this._sites_group_service.objectObs.endPoint ); - this.router.navigate(['monitorings', this.currentRoute, $event[$event.id], { edit: true }]); + this.router.navigate([ + '/monitorings/object/generic/', + this.currentRoute, + $event[$event.id], + { edit: true }, + ]); + } + + navigateToAddChildren($event) { + const row = $event; + if (row) { + row['id'] = row[row.pk]; + let queryParams = {}; + queryParams[row['pk']] = row['id']; + queryParams['parents_path'] = ['module', 'sites_group']; + + this.router.navigate(['/monitorings/object/generic/', row['object_type'], 'create'], { + queryParams: queryParams, + }); + } + } + + navigateToAddObj($event) { + const type = $event; + const queryParams = { + parents_path: ['module'], + }; + this.router.navigate(['/monitorings/object/generic/', type, 'create'], { + queryParams: queryParams, + }); } onDelete(event) { @@ -229,7 +257,7 @@ export class MonitoringSitesGroupsComponent extends MonitoringGeomComponent impl this.bDeleteModalEmitter.emit(false); this.activetabIndex = 0; this.currentRoute = 'sites_group'; - this.router.navigate(['/monitorings/sites_group', { delete: true }], { + this.router.navigate(['/monitorings/object/generic/sites_group', { delete: true }], { onSameUrlNavigation: 'reload', }); this.breadCrumbElementBase = breadCrumbBase.baseBreadCrumbSiteGroups.value; @@ -243,8 +271,8 @@ export class MonitoringSitesGroupsComponent extends MonitoringGeomComponent impl setTimeout(() => { this.bDeleteModalEmitter.emit(false); this.activetabIndex = 1; - this.currentRoute = 'sites'; - this.router.navigate(['/monitorings/sites', { delete: true }], { + this.currentRoute = 'site'; + this.router.navigate(['/monitorings/object/generic/site', { delete: true }], { onSameUrlNavigation: 'reload', }); this.breadCrumbElementBase = breadCrumbBase.baseBreadCrumbSites.value; @@ -256,12 +284,6 @@ export class MonitoringSitesGroupsComponent extends MonitoringGeomComponent impl } } - addSiteGpChild($event) { - this.router.navigate(['monitorings', this.currentRoute, $event[$event.pk], 'create'], { - replaceUrl: true, - }); - } - onSelectedOnDataTable(data) { const typeObject = data[0]; const id = data[1]; @@ -279,8 +301,8 @@ export class MonitoringSitesGroupsComponent extends MonitoringGeomComponent impl updateActiveTab($event) { if ($event == 'site') { this.activetabIndex = 1; - this.currentRoute = 'sites'; - this._location.go('/monitorings/sites'); + this.currentRoute = 'site'; + this._location.go('/monitorings/object/generic/site'); this.breadCrumbElementBase = breadCrumbBase.baseBreadCrumbSites.value; this.updateBreadCrumb(); this.geojsonService.removeFeatureGroup(this.geojsonService.sitesGroupFeatureGroup); @@ -288,7 +310,7 @@ export class MonitoringSitesGroupsComponent extends MonitoringGeomComponent impl } else { this.activetabIndex = 0; this.currentRoute = 'sites_group'; - this._location.go('/monitorings/sites_group'); + this._location.go('/monitorings/object/generic/sites_group'); this.breadCrumbElementBase = breadCrumbBase.baseBreadCrumbSiteGroups.value; this.updateBreadCrumb(); this.geojsonService.removeFeatureGroup(this.geojsonService.sitesFeatureGroup); @@ -336,7 +358,7 @@ export class MonitoringSitesGroupsComponent extends MonitoringGeomComponent impl } } - onAddChildren(event) { + addChildrenVisit(event) { if (event.objectType == 'site') { this.siteSelectedId = event.rowSelected[event.rowSelected['pk']]; this.getModules(); @@ -366,9 +388,9 @@ export class MonitoringSitesGroupsComponent extends MonitoringGeomComponent impl this._configJsonService.init(this.modulSelected.id).subscribe(() => { const moduleCode = this.modulSelected.id; const keys = Object.keys(this._configJsonService.config()[moduleCode]); - const parent_paths = ['sites_group', 'site'].filter((item) => keys.includes(item)); + const parents_path = ['sites_group', 'site'].filter((item) => keys.includes(item)); this.router.navigate([`monitorings/create_object/${moduleCode}/visit`], { - queryParams: { id_base_site: this.siteSelectedId, parents_path: parent_paths }, + queryParams: { id_base_site: this.siteSelectedId, parents_path: parents_path }, }); }); } diff --git a/frontend/app/gnModule.module.ts b/frontend/app/gnModule.module.ts index 6509d0cbb..f0b6cff35 100644 --- a/frontend/app/gnModule.module.ts +++ b/frontend/app/gnModule.module.ts @@ -38,9 +38,8 @@ import { MonitoringSitesGroupsComponent } from './components/monitoring-sitesgro import { DataTableService } from './services/data-table.service'; import { MonitoringPropertiesGComponent } from './components/monitoring-properties-g/monitoring-properties-g.component'; import { GeoJSONService } from './services/geojson.service'; -import { MonitoringSitesComponent } from './components/monitoring-sites/monitoring-sites.component'; +import { MonitoringSitesgroupsDetailComponent } from './components/monitoring-sitesgroups-detail/monitoring-sitesgroups-detail.component'; import { MonitoringMapListComponent } from './components/monitoring-map-list/monitoring-map-list.component'; -import { MonitoringFormComponentG } from './components/monitoring-form-g/monitoring-form.component-g'; import { FormService } from './services/form.service'; import { ObjectService } from './services/object.service'; import { PermissionService } from './services/permission.service'; @@ -53,7 +52,7 @@ import { 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 { MonitoringVisitsComponent } from './components/monitoring-visits/monitoring-visits.component'; +import { MonitoringSitesDetailComponent } from './components/monitoring-sites-detail/monitoring-sites-detail.component'; import { OptionListButtonComponent } from './components/option-list-btn/option-list-btn.component'; import { MatErrorMessagesDirective } from './utils/matErrorMessages.directive'; import { SitesGroupsReslver } from './resolver/sites-groups.resolver'; @@ -67,24 +66,34 @@ import { Popup } from './utils/popup'; const routes: Routes = [ /** modules */ { path: '', component: ModulesComponent }, - - /** module */ - { path: 'module/:moduleCode', component: MonitoringObjectComponent }, - /** create module */ - { path: 'module', component: MonitoringObjectComponent }, - - /** object */ - { - path: 'object/:moduleCode/:objectType/:id', - component: MonitoringObjectComponent, - }, - /** create object */ { - path: 'create_object/:moduleCode/:objectType', - component: MonitoringObjectComponent, + path: 'object/generic/site', + component: MonitoringMapListComponent, + children: [ + { + path: '', + component: MonitoringSitesGroupsComponent, + resolve: { + data: SitesGroupsReslver, + }, + runGuardsAndResolvers: 'always', + }, + { + path: 'create', + component: MonitoringSitesCreateComponent, + resolve: { + data: CreateSiteResolver, + }, + }, + { + path: ':id', + component: MonitoringSitesDetailComponent, + }, + ], }, + { - path: 'sites_group', + path: 'object/generic/sites_group', component: MonitoringMapListComponent, children: [ { @@ -104,7 +113,7 @@ const routes: Routes = [ children: [ { path: '', - component: MonitoringSitesComponent, + component: MonitoringSitesgroupsDetailComponent, }, { path: 'create', @@ -115,36 +124,26 @@ const routes: Routes = [ }, { path: 'site/:id', - component: MonitoringVisitsComponent, + component: MonitoringSitesDetailComponent, }, ], }, ], }, + /** module */ + { path: 'module/:moduleCode', component: MonitoringObjectComponent }, + /** create module */ + { path: 'module', component: MonitoringObjectComponent }, + + /** object */ { - path: 'sites', - component: MonitoringMapListComponent, - children: [ - { - path: '', - component: MonitoringSitesGroupsComponent, - resolve: { - data: SitesGroupsReslver, - }, - runGuardsAndResolvers: 'always', - }, - { - path: 'create', - component: MonitoringSitesCreateComponent, - resolve: { - data: CreateSiteResolver, - }, - }, - { - path: ':id', - component: MonitoringVisitsComponent, - }, - ], + path: 'object/:moduleCode/:objectType/:id', + component: MonitoringObjectComponent, + }, + /** create object */ + { + path: 'create_object/:moduleCode/:objectType', + component: MonitoringObjectComponent, }, { path: 'not-found', component: PageNotFoundComponent }, { path: '**', redirectTo: 'not-found' }, @@ -164,14 +163,13 @@ const routes: Routes = [ MonitoringDatatableComponent, MonitoringMapListComponent, MonitoringSitesGroupsComponent, - MonitoringSitesComponent, + MonitoringSitesgroupsDetailComponent, MonitoringDatatableGComponent, MonitoringPropertiesGComponent, - MonitoringFormComponentG, MonitoringSitesGroupsCreateComponent, MonitoringSitesCreateComponent, BtnSelectComponent, - MonitoringVisitsComponent, + MonitoringSitesDetailComponent, OptionListButtonComponent, MatErrorMessagesDirective, PageNotFoundComponent, diff --git a/frontend/app/interfaces/objObs.ts b/frontend/app/interfaces/objObs.ts index fd9722374..f149c4b26 100644 --- a/frontend/app/interfaces/objObs.ts +++ b/frontend/app/interfaces/objObs.ts @@ -8,12 +8,13 @@ export interface IobjObs { properties: T | {}; endPoint: endPoints; objectType: 'site' | 'sites_group' | 'visit'; - routeBase: 'sites' | 'sites_group' | 'visit'; + routeBase: 'site' | 'sites_group' | 'visit'; label: string; addObjLabel: string; editObjLabel: string; seeObjLabel: string; addChildLabel?: string; + childType?: string; deleteObjLabel: string; id: string | null; moduleCode: string; diff --git a/frontend/app/resolver/sites-groups.resolver.ts b/frontend/app/resolver/sites-groups.resolver.ts index d936d6d4d..6b4623678 100644 --- a/frontend/app/resolver/sites-groups.resolver.ts +++ b/frontend/app/resolver/sites-groups.resolver.ts @@ -91,7 +91,7 @@ export class SitesGroupsReslver return { sitesGroups: { data: siteGroups, objConfig: configs[0] }, sites: { data: sites, objConfig: configs[1] }, - route: route['_urlSegment'].segments[1].path, + route: route['_urlSegment'].segments[3].path, permission: this.currentPermission, }; }) diff --git a/frontend/app/services/api-geom.service.ts b/frontend/app/services/api-geom.service.ts index 386d07342..f43fd9b47 100644 --- a/frontend/app/services/api-geom.service.ts +++ b/frontend/app/services/api-geom.service.ts @@ -149,6 +149,7 @@ export class SitesGroupService extends ApiGeomService { editObjLabel: 'Editer le groupe de site', seeObjLabel: 'Consulter le groupe de site', addChildLabel: 'Ajouter un site', + childType: 'site', deleteObjLabel: 'Supprimer le groupe de site', id: null, moduleCode: 'generic', @@ -188,13 +189,14 @@ export class SitesService extends ApiGeomService { properties: {}, endPoint: endPoints.sites, objectType: 'site', - routeBase: 'sites', + routeBase: 'site', label: 'site', addObjLabel: 'Ajouter un nouveau site', editObjLabel: 'Editer le site', seeObjLabel: 'Consulter le site', deleteObjLabel: 'Supprimer le site', addChildLabel: 'Ajouter une visite', + childType: 'visit', id: null, moduleCode: 'generic', schema: {}, @@ -308,6 +310,7 @@ export class VisitsService extends ApiService { editObjLabel: 'Editer la visite', seeObjLabel: 'Consulter la visite', addChildLabel: 'Ajouter une observation', + childType: 'observation', deleteObjLabel: 'Supprimer la visite', routeBase: 'visit', id: null, diff --git a/frontend/app/services/config.service.ts b/frontend/app/services/config.service.ts index c8981ccef..8a07747f7 100644 --- a/frontend/app/services/config.service.ts +++ b/frontend/app/services/config.service.ts @@ -19,7 +19,6 @@ export class ConfigService { init(moduleCode: string | null = null) { // a definir ailleurs - moduleCode = moduleCode || 'generic'; if (this._config && this._config[moduleCode]) { @@ -147,7 +146,7 @@ export class ConfigService { /** Config Object Schema */ schema(moduleCode, objectType, typeSchema = 'all'): Object { - moduleCode = moduleCode || 'generic'; + moduleCode = moduleCode || 'MONITORINGS'; const configObject = this._config[moduleCode][objectType]; // gerer quand les paramètres ont un fonction comme valeur if (configObject) { diff --git a/frontend/app/services/data-utils.service.ts b/frontend/app/services/data-utils.service.ts index ec491ee51..042ebee00 100644 --- a/frontend/app/services/data-utils.service.ts +++ b/frontend/app/services/data-utils.service.ts @@ -239,7 +239,7 @@ export class DataUtilsService { // } getDataUtil(key) { - return this._cacheService['_cache']['util'][key]; + return (this._cacheService['_cache']['util'] || [])[key]; } getNomenclatures() { diff --git a/frontend/app/services/form.service.ts b/frontend/app/services/form.service.ts index f7b13b837..920822598 100644 --- a/frontend/app/services/form.service.ts +++ b/frontend/app/services/form.service.ts @@ -6,7 +6,7 @@ import { ISite, ISitesGroup } from '../interfaces/geom'; import { JsonData } from '../types/jsondata'; import { Utils } from '../utils/utils'; import { MonitoringObjectService } from './monitoring-object.service'; -import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; +import { FormBuilder, FormControl, FormGroup, FormArray, AbstractControl } from '@angular/forms'; import { IExtraForm, IFormMap } from '../interfaces/object'; import { ConfigService } from './config.service'; @@ -177,4 +177,143 @@ export class FormService { } return postData; } + + /** + * Add a form control to the object form. + * + * @param {Object} frmCtrl - The form control to add to the object form + * @param {FormGroup} objForm - The object form to add the form control to + * @return {Observable} The updated object form + */ + addFormCtrlToObjForm( + frmCtrl: { frmCtrl: FormControl; frmName: string }, + objForm: FormGroup + ): FormGroup { + if (frmCtrl.frmName in objForm.controls) { + // Si le champ existe déjà dans l'objet form, on ne fait rien + } else { + objForm.addControl(frmCtrl.frmName, frmCtrl.frmCtrl); + } + return objForm; + } + + /** + * Add multiple form groups to the object form. + * + * @param {Object} formGroups - Object containing form groups to add + * @param {FormGroup} targetForm - The target form group to add form groups to + * @return {FormGroup} The updated target form group + */ + addMultipleFormGroupsToObjForm( + formGroups: { [key: string]: FormGroup }, + targetForm: FormGroup + ): FormGroup { + // TODO ANALYSER ce qui est réeelement nécessaire + let dynamicGroups = targetForm.get('dynamicGroups') as FormArray; + + if (!dynamicGroups) { + dynamicGroups = this._formBuilder.array([]); + targetForm.addControl('dynamicGroups', dynamicGroups); + dynamicGroups = targetForm.get('dynamicGroups') as FormArray; // Refresh reference after adding it + } + + for (let i = dynamicGroups.controls.length - 1; i >= 0; i--) { + const control = dynamicGroups.controls[i]; + const controlName = control.get('name')?.value; + if (!formGroups[controlName]) { + dynamicGroups.removeAt(i); + } + } + + for (const key in formGroups) { + const existingControlIndex = dynamicGroups.controls.findIndex( + (control) => control.get('name')?.value === key + ); + + if (existingControlIndex !== -1) { + dynamicGroups.controls[existingControlIndex].patchValue(formGroups[key].value, { + emitEvent: false, + }); + } else { + const newControl = formGroups[key]; + newControl.addControl('name', this._formBuilder.control(key)); // Adding control with key as 'name' + dynamicGroups.push(newControl); + } + } + return targetForm; + } + + /** + * Patches values inside dynamic form groups + * + * @param valuesToPatch Values to patch, with the key being the control name and the value + * being the new value to set + * @param objOfFormGroups Object containing form groups to patch, with the key being the group name + * and the value being the form group + */ + patchValuesInDynamicGroups( + valuesToPatch: { [controlName: string]: any }, + objOfFormGroups: { [groupName: string]: FormGroup } + ): void { + Object.keys(objOfFormGroups).forEach((groupName) => { + const formGroup = objOfFormGroups[groupName]; + if (formGroup instanceof FormGroup) { + this.patchValuesInFormGroup(formGroup, valuesToPatch); + } + }); + } + + /** + * Patches values inside a form group + * + * @param formGroup Form group to patch values in + * @param valuesToPatch Values to patch, with the key being the control name and the value + * being the new value to set + */ + patchValuesInFormGroup(formGroup: FormGroup, valuesToPatch: JsonData): void { + Object.keys(valuesToPatch).forEach((controlName) => { + if (formGroup.contains(controlName)) { + formGroup.get(controlName).patchValue(valuesToPatch[controlName]); + } + }); + } + + /** + * Flattens a FormGroup into a JSON object. + * @param formGroup The FormGroup to flatten. + * @returns The flattened FormGroup as a JSON object. + */ + flattenFormGroup(formGroup: FormGroup): JsonData { + const flatObject: JsonData = {}; // JSON object to return + + // Recursive function to process nested controls + /** + * Flattens a control (or controls within a FormGroup or FormArray) into the + * flattened JSON object. + * @param control The control (or FormGroup or FormArray) to flatten. + * @param keyPrefix The prefix of the control's key to use in the flattened + * object. + */ + const flattenControl = (control: AbstractControl, keyPrefix: string = ''): void => { + if (control instanceof FormGroup) { + // If control is a FormGroup, recurse into its controls and flatten each one + Object.entries(control.controls).forEach(([controlName, nestedControl]) => { + flattenControl(nestedControl, `${controlName}.`); + }); + } else if (control instanceof FormArray) { + // If control is a FormArray, recurse into each control in the FormArray + control.controls.forEach((arrayControl, index) => { + flattenControl(arrayControl, `${keyPrefix}`); + }); + } else { + // If control is not a FormGroup or FormArray, add it to the flattened object + flatObject[keyPrefix.slice(0, -1)] = control.value; + } + }; + + // Start flattening from the root FormGroup + flattenControl(formGroup); + + return flatObject; + } } diff --git a/frontend/app/services/monitoring-object.service.ts b/frontend/app/services/monitoring-object.service.ts index 78d8100f1..e21d66cac 100644 --- a/frontend/app/services/monitoring-object.service.ts +++ b/frontend/app/services/monitoring-object.service.ts @@ -67,12 +67,12 @@ export class MonitoringObjectService { } } } - - for (const parentType of obj.parentTypes()) { - obj.getParent(parentType, 1).subscribe(() => { - this.setParentCache(obj, objData, parentType); - }); - } + // A voir si necéssaire pb dans le cas des groupes de site du gestionnaire de site + // for (const parentType of obj.parentTypes()) { + // obj.getParent(parentType, 1).subscribe(() => { + // this.setParentCache(obj, objData, parentType); + // }); + // } } setParentCache(obj: MonitoringObject, objData, parentType) { @@ -167,7 +167,7 @@ export class MonitoringObjectService { } configUtils(elem, moduleCode) { - return this._configService.config()[moduleCode].display_field_names[elem.type_util]; + return (this._configService.config()[moduleCode].display_field_names || [])[elem.type_util]; } toForm(elem, val): Observable { @@ -233,6 +233,9 @@ export class MonitoringObjectService { fromForm(elem, val) { let x = val; + if (x == undefined) { + return x; + } switch (elem.type_widget) { case 'date': { x = x && x.year && x.month && x.day ? `${x.year}-${x.month}-${x.day}` : null; @@ -302,4 +305,26 @@ export class MonitoringObjectService { } ); } + + navigateGeneric(routeType, moduleCode, objectType, id, action, 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, + } + ); + } } diff --git a/frontend/app/utils/popup.ts b/frontend/app/utils/popup.ts index bfd7980ac..46e8bbfe8 100644 --- a/frontend/app/utils/popup.ts +++ b/frontend/app/utils/popup.ts @@ -7,19 +7,56 @@ import { ConfigService } from '../services/config.service'; export class Popup { constructor(private _configService: ConfigService) {} - setPopup(url: string, feature, fieldName: string): string { + setPopup( + moduleCode: string, + objectType: string, + feature, + fieldId: string, + fieldName: string, + queryParams: {} + ): string { + const url = ['object', moduleCode, objectType, feature.properties[fieldId]].join('/'); + const fullurl = ['#', this._configService.frontendModuleMonitoringUrl(), url].join('/'); + const url_params = Object.keys(queryParams).length + ? '?' + + Object.keys(queryParams) + .map((key) => + Array.isArray(queryParams[key]) + ? queryParams[key].map((val) => `${key}=${val}`).join('&') + : `${key}=${queryParams[key]}` + ) + .join('&') + : ''; + const popup = `
-

${feature.properties[fieldName]}

+

${feature.properties[fieldName]}

${feature.properties['description'] || ''}
`; return popup; } - setSitePopup(feature): string { - const url = ['sites', feature.properties.id_base_site].join('/'); - return this.setPopup(url, feature, 'base_site_name'); + setSitePopup(moduleCode: string, feature, queryParams: {}) { + return this.setPopup( + moduleCode, + 'site', + feature, + 'id_base_site', + 'base_site_name', + queryParams + ); + } + + setSiteGroupPopup(moduleCode: string, feature, queryParams: {}) { + return this.setPopup( + moduleCode, + 'sites_group', + feature, + 'id_sites_group', + 'sites_group_name', + queryParams + ); } } diff --git a/frontend/app/utils/utils.ts b/frontend/app/utils/utils.ts index c02848fb9..c35eacab2 100644 --- a/frontend/app/utils/utils.ts +++ b/frontend/app/utils/utils.ts @@ -1,4 +1,5 @@ import { Observable } from 'rxjs/Observable'; +import { JsonData } from '../types/jsondata'; export class Utils { /** Fonction pour copier un objet de type dictionnaire */ @@ -66,4 +67,57 @@ export class Utils { return obj; } + + static getRemainingProperties(obj1: JsonData, obj2: JsonData): JsonData { + const remainingObj: JsonData = {}; + for (let key in obj1) { + if (!obj2.hasOwnProperty(key) || obj1[key] !== obj2[key]) { + remainingObj[key] = obj1[key]; + } + } + for (let key in obj2) { + if (!obj1.hasOwnProperty(key) || obj1[key] !== obj2[key]) { + remainingObj[key] = obj2[key]; + } + } + + return remainingObj; + } + + static getRemainingKeys(obj1, obj2): JsonData { + const remainingKeys = {}; + + // Iterate through the keys of obj1 + for (const key in obj1) { + // Check if the key does not exist in obj2 + if (!(key in obj2)) { + // Add the key and its value to the remainingKeys object + remainingKeys[key] = obj1[key]; + } + } + + return remainingKeys; + } + + static mergeObjects(obj1: JsonData, obj2: JsonData): JsonData { + const mergedObject: JsonData = { ...obj1 }; + for (const key in obj2) { + if (obj2.hasOwnProperty(key)) { + mergedObject[key] = obj2[key]; + } + } + + return mergedObject; + } + + static filterObject(objToFilt: JsonData, arrayUseToFilt: (string | number)[]): JsonData { + const keysToFilter: (string | number)[] = arrayUseToFilt.map(String) as (string | number)[]; + const filteredObject = Object.keys(objToFilt).reduce((obj, key) => { + if (keysToFilter.includes(key)) { + obj[key] = objToFilt[key]; + } + return obj; + }, {}); + return filteredObject; + } }