Skip to content

Commit

Permalink
Refactorisation et fusion de la gestion des formulaires (#349)
Browse files Browse the repository at this point in the history
* Remove customSpecConfig

* Limitation de l'appel à get_config

* Add test module config

* refact(wip): type site config with obj

Reviewed-by: andriacap

* refact(wip): init typeSite, generic and specific conf

Reviewed: andriaca

* refact(wip): make observable to init form componen

Reviewed-by: andriacap

* fix: change EMPTY to of(null)

Change return observable EMPTY by of(null)
in order to keep chained observable

Reviewed-by: andriacap

* refact(wip) : refact form component

Remove old methods
Use loop on dynamicForm

WIP: problem on initialize formControl (see
geonature/frontend/src/app/GN2CommonModule/form/dynamic-form-generator/dynamic-form-generator.component.ts)

Reviewed-by: andriacap

* refact: delete "dataComplement"

Remove dataComplement on form component
Remove dataComplement in backend on create_or_update
(called and used in pre_process) --> Check if
"TODO" code if is still necessary

Reviewed-by: andriacap

* refact:add extra dynamic form

On CREATION SITE
- Create objFormsDynamic
- Loop on these objFormsDynamic and display name for each group
- Update values for theses objFormsDynamic and link to objForm

TODO: Check if  EDITION SITE and other object type works

Reviewed-by: andriacap

* style: apply linter prettier

Reviewed-by: andriacap

* fix: unused code and fix condition

- Change condition to initFormDynamic
- Change condition to change typeSite on formValue

Reviewed-by: andriacap

* refact: changed way to subscribe to dynamicForm

- Remove place where variable called
- Centralize on subscribe of length of dynamicForm Array

Reviewed-by: andriacap

* fix: problem on init objFormDynamic on Edit object

- Need to filtered on types_site link to obj.properties['types_site']
- Add method to filtered (TODO: check if exist everywhere in utils ?)

Reviewed-by: andriacap

* fix/refact: change the way to initialize objForm

- Fix Problem on specific operator (the forkjoin didn't work)
- No more used of forkjoin and use defer in order to wait for specificValues$
is well completed before to subscribe and apply formValue

Reviewed-by: andriacap

* refact: remove unused code and use JSonData type

Reviewed-by: andriacap

* refact/fix: code bloc onInit and fix keep changes

- Fix: Problem on delete type site in dynamic form (keep changes and
re initialize values same as begining of edition)
- Refact(wip) : code on onInit to be more readable

Reviewed-by: andriacap

* refact(wip): more readable by separate concerns

Reviewed-by: andriacap

* refact(wip): move method to formService and utils

Reviewed-by: andriacap

* refact/doc: add docs and move dynamicForm$

- Move outside initialize typeSiteConfig to generate objFomDynamic
- Add doc for all methods added

Reviewed-by: andriacap

* fix: error for object without dynamicFormArray

Add check if dynamicFormArray exist in objForm

Reviewed-by: andriac

* refact: remove unused/useless code/commençant

Reviewed-by: andriacap

* style: lint frontend

Reviewed-by: andriacap

* Simplification code

* fix: remove return observable for objFormdefintion

- Remove return observable and remove pipe operator

Reviewed-by: andriac

* fix: check if list of types_site are integer

- FIXME : need to send only ids of types site
and not types site as string (fix in backend)

Reviewed-by: andriac

* fix: get all properties of additional data

Reviewed-by: andriacap

* fix: keep types sites prop from other modules

Backend :Need to add some code in backend to store extra
properties in order to find them in frontend

Frontend (form-component) : Get extra properties
stores in "additional_keys" in order to target them
when properties are filtered in post/patch method.

Reviewed-by: andriacp

* fix: use ids type site update when submit

Reviewed-by: andriacap

* Remove form-g and change route names

* Black

* refactor additionnal fields type site

* format

* fix update

* fix routing errors

* fix routing

* Use form component for site creation

* Rename component

* fix display properties in site manager

* Ne pas tenir compte du module lors de la récupération des sites parents

* Remove form-g + Routing

* Add child from datatable-g

* Prettier

* Navigation depuis le groupe de site

* Bloquer l'ajout de visite depuis generic site create

* Add parent path

* Popup

* Prettier

* Breadcrumb

* Correction pytest

* Router

* change permission order

* do not filter by module if generic module

* add missing grp_site object to monitoring module

* don't call group site group if no grp site

* fix routing

---------

Co-authored-by: Andria Capai <[email protected]>
Co-authored-by: TheoLechemia <[email protected]>
Co-authored-by: Théo Lechémia <[email protected]>
  • Loading branch information
4 people authored Jul 23, 2024
1 parent 3c4274d commit a738231
Show file tree
Hide file tree
Showing 50 changed files with 1,283 additions and 1,819 deletions.
11 changes: 11 additions & 0 deletions backend/gn_module_monitoring/config/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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(
Expand All @@ -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
Expand Down Expand Up @@ -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
;
"""
Expand All @@ -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')
)
"""
)
Expand All @@ -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')
;
"""
)
Expand All @@ -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')
;
"""
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

# revision identifiers, used by Alembic.
revision = "3ffeea74a9dd"
down_revision = "a5498a5f6022"
down_revision = "fc90d31c677f"
branch_labels = None
depends_on = None

Expand Down
Original file line number Diff line number Diff line change
@@ -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');
"""
)
7 changes: 5 additions & 2 deletions backend/gn_module_monitoring/monitoring/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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"):
"""
Expand Down
3 changes: 3 additions & 0 deletions backend/gn_module_monitoring/monitoring/geom.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions backend/gn_module_monitoring/monitoring/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
2 changes: 0 additions & 2 deletions backend/gn_module_monitoring/monitoring/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
Expand Down
27 changes: 25 additions & 2 deletions backend/gn_module_monitoring/monitoring/serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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 = {}
Expand All @@ -80,14 +88,28 @@ 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
data[attribut_name] = val

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)
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions backend/gn_module_monitoring/routes/data_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}

Expand Down
5 changes: 4 additions & 1 deletion backend/gn_module_monitoring/routes/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ def get_modules_api():
@blueprint.route("/modules/<string:module_code>/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]
4 changes: 3 additions & 1 deletion backend/gn_module_monitoring/routes/monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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:
Expand Down
13 changes: 5 additions & 8 deletions backend/gn_module_monitoring/utils/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
4 changes: 2 additions & 2 deletions frontend/app/class/breadCrumb.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
Loading

0 comments on commit a738231

Please sign in to comment.