Skip to content

Commit

Permalink
Added: new metadata fields for linked users and forms (#280) (#281)
Browse files Browse the repository at this point in the history
  • Loading branch information
signebedi committed Jun 24, 2024
1 parent 33c40bb commit a65b12c
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
17 changes: 13 additions & 4 deletions libreforms_fastapi/app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,11 @@ async def api_form_create(
except ValidationError as e:
raise HTTPException(status_code=422, detail=f"There was an error with one of your fields: {e}")


# Here we pull metadata on how to handle fields that link to
# users and other forms.
user_fields, form_fields = form_data.get_additional_metadata()


json_data = form_data.model_dump_json()
# print("\n\n\n", json_data)
data_dict = form_data.model_dump()
Expand All @@ -791,6 +795,8 @@ async def api_form_create(
doc_db.document_id_field: document_id,
doc_db.created_by_field: user.username,
doc_db.last_editor_field: user.username,
doc_db.linked_to_user_field: user_fields,
doc_db.linked_to_form_field: form_fields,
}

# Add the remote addr host if enabled
Expand Down Expand Up @@ -1267,11 +1273,11 @@ async def api_form_update(
doc_db=doc_db,
)

# # Here we validate and coerce data into its proper type
# Here we validate and coerce data into its proper type
form_data = FormModel.model_validate(body)
json_data = form_data.model_dump_json()
data_dict = form_data.model_dump()

# print("\n\n\n", json_data)

# Ugh, I'd like to find a more efficient way to get the user data. But alas, that
Expand Down Expand Up @@ -4722,7 +4728,10 @@ async def ui_form_read_one(form_name:str, document_id:str, request: Request, con
raise HTTPException(status_code=404)

# Here we create a mask of metadata field names for the UI
metadata_field_mask = {x: x.replace("_", " ").title() for x in doc_db.metadata_fields if x not in [doc_db.journal_field]}
metadata_field_mask = {
x: x.replace("_", " ").title() for x in doc_db.metadata_fields
if x not in [doc_db.journal_field, doc_db.linked_to_user_field, doc_db.linked_to_form_field]
}

# # Here we load the form config in order to mask data field names correctly
form_config = load_form_config(config.FORM_CONFIG_PATH)
Expand Down
8 changes: 6 additions & 2 deletions libreforms_fastapi/utils/document_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ def _initialize_metadata_fields(self):
# self.approved_by_field = "approved_by"
# self.approval_signature_field = "approval_signature"
self.journal_field = "journal"
self.user_fields = "user_fields"
self.linked_to_user_field = "linked_user_fields"
# [self.created_by_field, self.last_editor_field, field_name, field_name]
self.form_fields = "form_fields"
self.linked_to_form_field = "linked_form_fields"
# [(field_name, form_name, [display_field, display_field])]

return [
Expand All @@ -216,6 +216,8 @@ def _initialize_metadata_fields(self):
# self.approved_by_field,
# self.approval_signature_field,
self.journal_field,
self.linked_to_user_field,
self.linked_to_form_field,
]
@abstractmethod
def _initialize_database_collections(self):
Expand Down Expand Up @@ -462,6 +464,8 @@ def create_document(
self.created_by_field: metadata.get(self.created_by_field, None),
self.signature_field: metadata.get(self.signature_field, {}),
self.last_editor_field: metadata.get(self.last_editor_field, None),
self.linked_to_user_field: metadata.get(self.linked_to_user_field, []),
self.linked_to_form_field: metadata.get(self.linked_to_form_field, {}),
# self.approved_field: metadata.get(self.approved_field, None),
# self.approved_by_field: metadata.get(self.approved_by_field, None),
# self.approval_signature_field: metadata.get(self.approval_signature_field, None),
Expand Down
28 changes: 28 additions & 0 deletions libreforms_fastapi/utils/pydantic_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,10 @@ def get_form_model(
fields = form_config[form_name]
field_definitions = {}

# Initialize empty data structures
user_fields = [] # https://github.com/signebedi/libreforms-fastapi/issues/281
form_fields = {} # https://github.com/signebedi/libreforms-fastapi/issues/280

class Config:
arbitrary_types_allowed = True

Expand All @@ -564,6 +568,17 @@ class Config:
if field_info.get("is_header", False):
continue

# If this field links to a user account, then append that field to the
# user_fields list, see https://github.com/signebedi/libreforms-fastapi/issues/281
if field_info.get("links_to_user", False):
user_fields.append(field_name)

# If this field links to another form, then add that to the form_fields
# data structure, see https://github.com/signebedi/libreforms-fastapi/issues/280
_links_to_form = field_info.get("links_to_form", False)
if isinstance(_links_to_form, str):
form_fields[field_name] = _links_to_form

python_type = field_info["output_type"]
default_value = None if update else field_info.get("default", ...)
required = field_info.get("required", False)
Expand Down Expand Up @@ -592,6 +607,19 @@ class Config:
# Create dynamic model
dynamic_model = create_model(form_name, __config__=Config, **field_definitions)


def get_additional_metadata(self):
"""
Return additional metadata for the form based on the form config. Added based on
the discussion in https://github.com/signebedi/libreforms-fastapi/issues/280
and https://github.com/signebedi/libreforms-fastapi/issues/281.
"""

return user_fields, form_fields

# Attach the method to the dynamic model
dynamic_model.get_additional_metadata = get_additional_metadata

return dynamic_model

def get_form_html(
Expand Down

0 comments on commit a65b12c

Please sign in to comment.