- Add a new 'system' type to dynamic forms, first one defined = 'tenant_make'
- Add active field to Specialist model - Improve Specialists view - Propagate make for Role Definition Specialist to Selection Specialist (make is defined at the role level) - Ensure a make with a given name can only be defined once
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<form method="POST" action="{{ url_for('interaction_bp.handle_specialist_selection') }}" id="specialistsForm">
|
||||
{{ render_selectable_table(headers=["Specialist ID", "Name", "Type"], rows=rows, selectable=True, id="specialistsTable") }}
|
||||
{{ render_selectable_table(headers=["Specialist ID", "Name", "Type", "Type Version", "Active"], rows=rows, selectable=True, id="specialistsTable") }}
|
||||
<div class="form-group mt-3 d-flex justify-content-between">
|
||||
<div>
|
||||
<button type="submit" name="action" value="edit_specialist" class="btn btn-primary" onclick="return validateTableSelection('specialistsForm')">Edit Specialist</button>
|
||||
|
||||
@@ -3,12 +3,14 @@ from datetime import date
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import (IntegerField, FloatField, BooleanField, StringField, TextAreaField, FileField,
|
||||
validators, ValidationError)
|
||||
from flask import current_app, request
|
||||
from flask import current_app, request, session
|
||||
import json
|
||||
|
||||
from wtforms.fields.choices import SelectField
|
||||
from wtforms.fields.datetime import DateField
|
||||
from wtforms.fields.simple import ColorField
|
||||
|
||||
from common.models.user import TenantMake
|
||||
from common.utils.config_field_types import TaggingFields, json_to_patterns, patterns_to_json
|
||||
|
||||
|
||||
@@ -300,6 +302,22 @@ class DynamicFormBase(FlaskForm):
|
||||
except Exception as e:
|
||||
raise ValidationError(f"Invalid ordered list: {str(e)}")
|
||||
|
||||
def _get_system_field(self, system_name):
|
||||
"""Get the field class and kwargs for a system field. Add system field cases as you need them."""
|
||||
field_class = None
|
||||
extra_classes = ''
|
||||
field_kwargs = {}
|
||||
match system_name:
|
||||
case 'tenant_make':
|
||||
field_class = SelectField
|
||||
tenant_id = session.get('tenant').get('id')
|
||||
makes = TenantMake.query.filter_by(tenant_id=tenant_id).all()
|
||||
choices = [(make.name, make.name) for make in makes]
|
||||
extra_classes = ''
|
||||
field_kwargs = {'choices': choices}
|
||||
|
||||
return field_class, extra_classes, field_kwargs
|
||||
|
||||
def add_dynamic_fields(self, collection_name, config, initial_data=None):
|
||||
"""Add dynamic fields to the form based on the configuration.
|
||||
|
||||
@@ -357,11 +375,12 @@ class DynamicFormBase(FlaskForm):
|
||||
extra_classes = ['monospace-text', 'pattern-input']
|
||||
field_kwargs = {}
|
||||
elif field_type == 'ordered_list':
|
||||
current_app.logger.debug(f"Adding ordered list field for {full_field_name}")
|
||||
field_class = OrderedListField
|
||||
extra_classes = ''
|
||||
list_type = field_def.get('list_type', '')
|
||||
field_kwargs = {'list_type': list_type}
|
||||
elif field_type == 'system':
|
||||
field_class, extra_classes, field_kwargs = self._get_system_field(field_def.get('system_name', ''))
|
||||
else:
|
||||
extra_classes = ''
|
||||
field_class = {
|
||||
|
||||
@@ -24,6 +24,7 @@ def get_tools():
|
||||
|
||||
class SpecialistForm(FlaskForm):
|
||||
name = StringField('Name', validators=[DataRequired(), Length(max=50)])
|
||||
description = TextAreaField('Description', validators=[Optional()])
|
||||
|
||||
retrievers = QuerySelectMultipleField(
|
||||
'Retrievers',
|
||||
@@ -34,7 +35,7 @@ class SpecialistForm(FlaskForm):
|
||||
)
|
||||
|
||||
type = SelectField('Specialist Type', validators=[DataRequired()])
|
||||
|
||||
active = BooleanField('Active', validators=[Optional()], default=True)
|
||||
tuning = BooleanField('Enable Specialist Tuning', default=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -47,6 +48,7 @@ class SpecialistForm(FlaskForm):
|
||||
class EditSpecialistForm(DynamicFormBase):
|
||||
name = StringField('Name', validators=[DataRequired()])
|
||||
description = TextAreaField('Description', validators=[Optional()])
|
||||
active = BooleanField('Active', validators=[Optional()], default=True)
|
||||
|
||||
retrievers = QuerySelectMultipleField(
|
||||
'Retrievers',
|
||||
|
||||
@@ -162,6 +162,7 @@ def specialist():
|
||||
new_specialist.type = form.type.data
|
||||
new_specialist.type_version = cache_manager.specialists_version_tree_cache.get_latest_version(
|
||||
new_specialist.type)
|
||||
new_specialist.active = form.active.data
|
||||
new_specialist.tuning = form.tuning.data
|
||||
|
||||
set_logging_information(new_specialist, dt.now(tz.utc))
|
||||
@@ -231,6 +232,7 @@ def edit_specialist(specialist_id):
|
||||
specialist.name = form.name.data
|
||||
specialist.description = form.description.data
|
||||
specialist.tuning = form.tuning.data
|
||||
specialist.active = form.active.data
|
||||
# Update the configuration dynamic fields
|
||||
specialist.configuration = form.get_dynamic_data("configuration")
|
||||
|
||||
@@ -297,7 +299,7 @@ def specialists():
|
||||
|
||||
# prepare table data
|
||||
rows = prepare_table_for_macro(the_specialists,
|
||||
[('id', ''), ('name', ''), ('type', '')])
|
||||
[('id', ''), ('name', ''), ('type', ''), ('type_version', ''), ('active', ''),])
|
||||
|
||||
# Render the catalogs in a template
|
||||
return render_template('interaction/specialists.html', rows=rows, pagination=pagination)
|
||||
|
||||
@@ -2,10 +2,12 @@ from flask import current_app, session
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import (StringField, BooleanField, SubmitField, EmailField, IntegerField, DateField,
|
||||
SelectField, SelectMultipleField, FieldList, FormField, TextAreaField)
|
||||
from wtforms.validators import DataRequired, Length, Email, NumberRange, Optional
|
||||
from wtforms.validators import DataRequired, Length, Email, NumberRange, Optional, ValidationError
|
||||
import pytz
|
||||
from flask_security import current_user
|
||||
from wtforms.widgets.core import HiddenInput
|
||||
|
||||
from common.models.user import TenantMake
|
||||
from common.services.user import UserServices
|
||||
from config.type_defs.service_types import SERVICE_TYPES
|
||||
from eveai_app.views.dynamic_form_base import DynamicFormBase
|
||||
@@ -132,8 +134,19 @@ class EditTenantProjectForm(FlaskForm):
|
||||
self.services.choices = [(key, value['description']) for key, value in SERVICE_TYPES.items()]
|
||||
|
||||
|
||||
def validate_make_name(form, field):
|
||||
# Controleer of een TenantMake met deze naam al bestaat
|
||||
existing_make = TenantMake.query.filter_by(name=field.data).first()
|
||||
|
||||
# Als er een bestaande make is gevonden en we zijn niet in edit mode,
|
||||
# of als we wel in edit mode zijn maar het is een ander record (andere id)
|
||||
if existing_make and (not hasattr(form, 'id') or form.id.data != existing_make.id):
|
||||
raise ValidationError(f'A Make with name "{field.data}" already exists. Choose another name.')
|
||||
|
||||
|
||||
class TenantMakeForm(DynamicFormBase):
|
||||
name = StringField('Name', validators=[DataRequired(), Length(max=50)])
|
||||
id = IntegerField('ID', widget=HiddenInput())
|
||||
name = StringField('Name', validators=[DataRequired(), Length(max=50), validate_make_name])
|
||||
description = TextAreaField('Description', validators=[Optional()])
|
||||
active = BooleanField('Active', validators=[Optional()], default=True)
|
||||
website = StringField('Website', validators=[DataRequired(), Length(max=255)])
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import json
|
||||
import uuid
|
||||
from datetime import datetime as dt, timezone as tz
|
||||
from flask import request, redirect, flash, render_template, Blueprint, session, current_app
|
||||
@@ -627,15 +628,17 @@ def delete_tenant_project(tenant_project_id):
|
||||
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
|
||||
def tenant_make():
|
||||
form = TenantMakeForm()
|
||||
customisation_config = cache_manager.customisations_config_cache.get_config("CHAT_CLIENT_CUSTOMISATION")
|
||||
default_customisation_options = create_default_config_from_type_config(customisation_config["configuration"])
|
||||
form.add_dynamic_fields("configuration", customisation_config, default_customisation_options)
|
||||
|
||||
if form.validate_on_submit():
|
||||
tenant_id = session['tenant']['id']
|
||||
new_tenant_make = TenantMake()
|
||||
form.populate_obj(new_tenant_make)
|
||||
new_tenant_make.tenant_id = tenant_id
|
||||
customisation_config = cache_manager.customisations_config_cache.get_config("CHAT_CLIENT_CUSTOMISATION")
|
||||
new_tenant_make.chat_customisation_options = create_default_config_from_type_config(
|
||||
customisation_config["configuration"])
|
||||
form.add_dynamic_fields("configuration", customisation_config, new_tenant_make.chat_customisation_options)
|
||||
customisation_options = form.get_dynamic_data("configuration")
|
||||
new_tenant_make.chat_customisation_options = json.dumps(customisation_options)
|
||||
set_logging_information(new_tenant_make, dt.now(tz.utc))
|
||||
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user