added attribute types: TextMultilingual, multiselect
This commit is contained in:
parent
d009f93dba
commit
72f5fbde46
4 changed files with 84 additions and 15 deletions
|
|
@ -5,6 +5,7 @@ from typing import Optional, Dict
|
|||
from enum import Enum
|
||||
from pydantic import BaseModel, Field
|
||||
from modules.shared.attributeUtils import registerModelLabels
|
||||
from modules.datamodels.datamodelUtils import TextMultilingual
|
||||
from modules.datamodels.datamodelUam import AccessLevel
|
||||
|
||||
|
||||
|
|
@ -26,9 +27,9 @@ class Role(BaseModel):
|
|||
description="Unique role label identifier (e.g., 'admin', 'user', 'viewer')",
|
||||
json_schema_extra={"frontend_type": "text", "frontend_readonly": False, "frontend_required": True}
|
||||
)
|
||||
description: Dict[str, str] = Field(
|
||||
description: TextMultilingual = Field(
|
||||
description="Role description in multiple languages",
|
||||
json_schema_extra={"frontend_type": "object", "frontend_readonly": False, "frontend_required": True}
|
||||
json_schema_extra={"frontend_type": "multilingual", "frontend_readonly": False, "frontend_required": True}
|
||||
)
|
||||
isSystemRole: bool = Field(
|
||||
False,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""Utility datamodels: Prompt."""
|
||||
"""Utility datamodels: Prompt, TextMultilingual."""
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Dict, Optional
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
from modules.shared.attributeUtils import registerModelLabels
|
||||
import uuid
|
||||
|
||||
|
|
@ -22,3 +23,49 @@ registerModelLabels(
|
|||
)
|
||||
|
||||
|
||||
class TextMultilingual(BaseModel):
|
||||
"""
|
||||
Multilingual text field supporting multiple languages.
|
||||
Default languages: en (English), ge (German), fr (French), it (Italian)
|
||||
English (en) is the default/required language.
|
||||
"""
|
||||
en: str = Field(description="English text (default language, required)")
|
||||
ge: Optional[str] = Field(None, description="German text")
|
||||
fr: Optional[str] = Field(None, description="French text")
|
||||
it: Optional[str] = Field(None, description="Italian text")
|
||||
|
||||
@field_validator('en')
|
||||
@classmethod
|
||||
def validate_en_required(cls, v):
|
||||
"""Ensure English text is not empty"""
|
||||
if not v or not v.strip():
|
||||
raise ValueError("English text (en) is required and cannot be empty")
|
||||
return v
|
||||
|
||||
def model_dump(self, **kwargs) -> Dict[str, str]:
|
||||
"""Return as dictionary, filtering out None values"""
|
||||
result = {}
|
||||
for lang in ['en', 'ge', 'fr', 'it']:
|
||||
value = getattr(self, lang, None)
|
||||
if value is not None:
|
||||
result[lang] = value
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: Dict[str, str]) -> 'TextMultilingual':
|
||||
"""Create TextMultilingual from dictionary"""
|
||||
return cls(
|
||||
en=data.get('en', ''),
|
||||
ge=data.get('ge'),
|
||||
fr=data.get('fr'),
|
||||
it=data.get('it')
|
||||
)
|
||||
|
||||
def get_text(self, lang: str = 'en') -> str:
|
||||
"""Get text for a specific language, fallback to English if not available"""
|
||||
value = getattr(self, lang, None)
|
||||
if value:
|
||||
return value
|
||||
return self.en # Fallback to English
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,17 @@ def getOptions(optionsName: str, currentUser: Optional[User] = None) -> List[Dic
|
|||
options = []
|
||||
for role in roles:
|
||||
# Use English description as label, fallback to roleLabel
|
||||
label = role.description.get("en", role.roleLabel) if isinstance(role.description, dict) else role.roleLabel
|
||||
# Handle TextMultilingual object
|
||||
if hasattr(role.description, 'get_text'):
|
||||
# TextMultilingual object
|
||||
label = role.description.get_text('en')
|
||||
elif isinstance(role.description, dict):
|
||||
# Dict format (backward compatibility)
|
||||
label = role.description.get("en", role.roleLabel)
|
||||
else:
|
||||
# Fallback to roleLabel
|
||||
label = role.roleLabel
|
||||
|
||||
options.append({
|
||||
"value": role.roleLabel,
|
||||
"label": label
|
||||
|
|
|
|||
|
|
@ -166,16 +166,27 @@ def getModelAttributeDefinitions(modelClass: Type[BaseModel] = None, userLanguag
|
|||
if frontend_options is None and "frontend_options" in json_extra:
|
||||
frontend_options = json_extra.get("frontend_options")
|
||||
|
||||
# Use frontend type if available, otherwise fall back to Python type
|
||||
field_type = (
|
||||
frontend_type
|
||||
if frontend_type
|
||||
else (
|
||||
field.annotation.__name__
|
||||
if hasattr(field.annotation, "__name__")
|
||||
else str(field.annotation)
|
||||
)
|
||||
)
|
||||
# Use frontend type if available, otherwise detect from Python type
|
||||
if frontend_type:
|
||||
field_type = frontend_type
|
||||
else:
|
||||
# Check if it's TextMultilingual type
|
||||
annotation_str = str(field.annotation)
|
||||
# Check both the module path and class name for TextMultilingual
|
||||
if ('TextMultilingual' in annotation_str or
|
||||
(hasattr(field.annotation, '__name__') and field.annotation.__name__ == 'TextMultilingual') or
|
||||
'datamodelUtils.TextMultilingual' in annotation_str or
|
||||
'datamodels.datamodelUtils.TextMultilingual' in annotation_str):
|
||||
field_type = 'multilingual'
|
||||
elif hasattr(field.annotation, "__name__"):
|
||||
annotation_name = field.annotation.__name__
|
||||
# Check if it's a Dict type (for JSON/object fields)
|
||||
if annotation_name == 'Dict' or annotation_str.startswith('typing.Dict') or annotation_str.startswith('Dict['):
|
||||
field_type = 'object' # Will be rendered as textarea for JSON editing
|
||||
else:
|
||||
field_type = annotation_name
|
||||
else:
|
||||
field_type = str(field.annotation)
|
||||
|
||||
# Extract default value from field
|
||||
# In Pydantic v2, FieldInfo has a 'default' attribute
|
||||
|
|
|
|||
Loading…
Reference in a new issue