- Fixed Error where Catalog Types other than default could not be added

- Fixed error in TRAICIE_KO_INTERVIEW_DEFINITION_SPECIALIST
- Minor improvements
This commit is contained in:
Josako
2025-07-25 22:35:08 +02:00
parent ba523a95c5
commit 42ffe3795f
13 changed files with 258 additions and 102 deletions

View File

@@ -26,7 +26,7 @@
<div class="col-md-6">
<p><strong>Type Version:</strong> {{ asset.type_version }}</p>
<p><strong>File Type:</strong> {{ asset.file_type }}</p>
<p><strong>File Size:</strong> {{ asset.file_size or 'N/A' }} bytes</p>
<p><strong>File Size:</strong> {{ asset.file_size or 'N/A' }} MiB</p>
</div>
</div>

View File

@@ -0,0 +1,41 @@
{% extends 'base.html' %}
{% from "macros.html" import render_field %}
{% block title %}Specialist Magic Link URLs{% endblock %}
{% block content_title %}Specialist Magic Link URLs{% endblock %}
{% block content_description %}View URL and QR Code for a Magic Link{% endblock %}
{% block content %}
<form method="post">
{{ form.hidden_tag() }}
{% set disabled_fields = [] %}
{% set exclude_fields = [] %}
{% for field in form %}
{% if field.name == 'qr_code_url' and field.data %}
<div class="form-group">
<label for="{{ field.id }}">{{ field.label.text }}</label>
<div style="max-width: 200px;">
<img src="{{ field.data }}" alt="QR Code" class="img-fluid">
</div>
<input type="hidden" name="{{ field.name }}" value="{{ field.data|e }}">
</div>
{% elif field.name == 'chat_client_url' %}
<div class="form-group">
<label for="{{ field.id }}" class="form-label">{{ field.label.text }}</label>
<div class="input-group">
<input type="text" class="form-control" value="{{ field.data }}" id="{{ field.id }}" readonly>
<a href="{{ field.data }}" class="btn btn-primary" target="_blank">Open link</a>
</div>
<input type="hidden" name="{{ field.name }}" value="{{ field.data|e }}">
</div>
{% else %}
{{ render_field(field, disabled_fields, exclude_fields) }}
{% endif %}
{% endfor %}
</form>
{% endblock %}
{% block content_footer %}
{% endblock %}

View File

@@ -392,7 +392,7 @@ def add_document():
flash(f'Processing on document {new_doc.name}, version {new_doc_vers.id} started. Task ID: {task_id}.',
'success')
return redirect(prefixed_url_for('document_bp.documents'))
return redirect(prefixed_url_for('document_bp.documents_processing'))
except EveAIException as e:
flash(str(e), 'error')
@@ -451,7 +451,7 @@ def add_url():
flash(f'Processing on document {new_doc.name}, version {new_doc_vers.id} started. Task ID: {task_id}.',
'success')
return redirect(prefixed_url_for('document_bp.documents'))
return redirect(prefixed_url_for('document_bp.documents_processing'))
except EveAIException as e:
current_app.logger.error(f"Error adding document: {str(e)}")

View File

@@ -134,8 +134,7 @@ class EditSpecialistMagicLinkForm(DynamicFormBase):
render_kw={'readonly': True})
specialist_id = IntegerField('Specialist', validators=[DataRequired()], render_kw={'readonly': True})
specialist_name = StringField('Specialist Name', validators=[DataRequired()], render_kw={'readonly': True})
chat_client_url = StringField('Chat Client URL', validators=[Optional()], render_kw={'readonly': True})
qr_code_url = StringField('QR Code', validators=[Optional()], render_kw={'readonly': True})
tenant_make_id = SelectField('Tenant Make', validators=[Optional()], coerce=int)
valid_from = DateField('Valid From', id='form-control datepicker', validators=[Optional()])
valid_to = DateField('Valid To', id='form-control datepicker', validators=[Optional()])
@@ -158,5 +157,14 @@ class EditSpecialistMagicLinkForm(DynamicFormBase):
self.tenant_make_id.choices = [(0, 'None')] + [(make.id, make.name) for make in tenant_makes]
class ViewSpecialistMagicLinkURLsForm(FlaskForm):
name = StringField('Name', validators=[DataRequired(), Length(max=50)])
description = TextAreaField('Description', validators=[Optional()])
magic_link_code = StringField('Magic Link Code', validators=[DataRequired(), Length(max=55)], render_kw={'readonly': True})
chat_client_url = StringField('Chat Client URL', validators=[Optional()], render_kw={'readonly': True})
qr_code_url = StringField('QR Code', validators=[Optional()], render_kw={'readonly': True})

View File

@@ -29,7 +29,7 @@ from common.utils.view_assistants import form_validation_failed, prepare_table_f
from .interaction_forms import (SpecialistForm, EditSpecialistForm, EditEveAIAgentForm, EditEveAITaskForm,
EditEveAIToolForm, ExecuteSpecialistForm,
SpecialistMagicLinkForm, EditSpecialistMagicLinkForm)
SpecialistMagicLinkForm, EditSpecialistMagicLinkForm, ViewSpecialistMagicLinkURLsForm)
from eveai_app.views.list_views.interaction_list_views import (get_specialists_list_view, get_assets_list_view,
get_magic_links_list_view, get_chat_sessions_list_view,
@@ -648,52 +648,6 @@ def edit_specialist_magic_link(specialist_magic_link_id):
else:
form.tenant_make_id.data = specialist_ml.tenant_make_id
# Set the chat client URL
tenant_id = session.get('tenant').get('id')
chat_client_prefix = current_app.config.get('CHAT_CLIENT_PREFIX', 'chat_client/chat/')
base_url = request.url_root
magic_link_code = specialist_ml.magic_link_code
# Parse the URL om poortinformatie te behouden als deze afwijkt van de standaard
url_parts = request.url.split('/')
host_port = url_parts[2] # Dit bevat zowel hostname als poort indien aanwezig
# Generate the full URL for chat client with magic link code
chat_client_url = f"{request.scheme}://{host_port}/{chat_client_prefix}{magic_link_code}"
form.chat_client_url.data = chat_client_url
# Generate QR code as data URI for direct embedding in HTML
try:
import qrcode
import io
import base64
# Generate QR code as PNG for better compatibility
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4
)
qr.add_data(chat_client_url)
qr.make(fit=True)
# Generate PNG image in memory
img = qr.make_image(fill_color="black", back_color="white")
buffer = io.BytesIO()
img.save(buffer, format='PNG')
img_data = buffer.getvalue()
# Create data URI for direct embedding in HTML
img_base64 = base64.b64encode(img_data).decode('utf-8')
data_uri = f"data:image/png;base64,{img_base64}"
# Store the data URI in the form data
form.qr_code_url.data = data_uri
except Exception as e:
current_app.logger.error(f"Failed to generate QR code: {str(e)}")
form.qr_code_url.data = "Error generating QR code"
if form.validate_on_submit():
# Update the basic fields
form.populate_obj(specialist_ml)
@@ -722,6 +676,61 @@ def edit_specialist_magic_link(specialist_magic_link_id):
return render_template('interaction/edit_specialist_magic_link.html', form=form)
@interaction_bp.route('/view_specialist_magic_link_urls/<int:specialist_magic_link_id>', methods=['GET'])
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
def view_specialist_magic_link_urls(specialist_magic_link_id):
specialist_ml = SpecialistMagicLink.query.get_or_404(specialist_magic_link_id)
form = ViewSpecialistMagicLinkURLsForm(obj=specialist_ml)
# Set the chat client URL
tenant_id = session.get('tenant').get('id')
chat_client_prefix = current_app.config.get('CHAT_CLIENT_PREFIX', 'chat_client/chat/')
base_url = request.url_root
magic_link_code = specialist_ml.magic_link_code
# Parse the URL om poortinformatie te behouden als deze afwijkt van de standaard
url_parts = request.url.split('/')
host_port = url_parts[2] # Dit bevat zowel hostname als poort indien aanwezig
# Generate the full URL for chat client with magic link code
chat_client_url = f"{request.scheme}://{host_port}/{chat_client_prefix}{magic_link_code}"
form.chat_client_url.data = chat_client_url
# Generate QR code as data URI for direct embedding in HTML
try:
import qrcode
import io
import base64
# Generate QR code as PNG for better compatibility
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4
)
qr.add_data(chat_client_url)
qr.make(fit=True)
# Generate PNG image in memory
img = qr.make_image(fill_color="black", back_color="white")
buffer = io.BytesIO()
img.save(buffer, format='PNG')
img_data = buffer.getvalue()
# Create data URI for direct embedding in HTML
img_base64 = base64.b64encode(img_data).decode('utf-8')
data_uri = f"data:image/png;base64,{img_base64}"
# Store the data URI in the form data
form.qr_code_url.data = data_uri
except Exception as e:
current_app.logger.error(f"Failed to generate QR code: {str(e)}")
form.qr_code_url.data = "Error generating QR code"
return render_template('interaction/view_specialist_magic_link_urls.html', form=form)
@interaction_bp.route('/specialist_magic_links', methods=['GET', 'POST'])
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
def specialist_magic_links():
@@ -743,6 +752,9 @@ def handle_specialist_magic_link_selection():
if action == "edit_specialist_magic_link":
return redirect(prefixed_url_for('interaction_bp.edit_specialist_magic_link',
specialist_magic_link_id=specialist_ml_id))
if action == "view_specialist_magic_link_urls":
return redirect(prefixed_url_for('interaction_bp.view_specialist_magic_link_urls',
specialist_magic_link_id=specialist_ml_id))
return redirect(prefixed_url_for('interaction_bp.specialists'))

View File

@@ -132,7 +132,8 @@ def get_magic_links_list_view():
# Action definitions
actions = [
{'value': 'edit_specialist_magic_link', 'text': 'Edit Magic Link', 'class': 'btn-primary', 'requiresSelection': True},
{'value': 'create_specialist_magic_link', 'text': 'Create Magic Link', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False}
{'value': 'view_specialist_magic_link_urls', 'text': 'View Magic Link URLs', 'class': 'btn-secondary', 'requiresSelection': True},
{'value': 'create_specialist_magic_link', 'text': 'Create Magic Link', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False},
]
# Initial sort configuration