Introduction of Partner Model, adding code to Tenant model
This commit is contained in:
18
eveai_app/templates/administration/edit_partner.html
Normal file
18
eveai_app/templates/administration/edit_partner.html
Normal file
@@ -0,0 +1,18 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "macros.html" import render_field %}
|
||||
{% block title %}Update Partner{% endblock %}
|
||||
|
||||
{% block content_title %}Update Partner{% endblock %}
|
||||
{% block content_description %}Update partner{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
{{ form.hidden_tag() }}
|
||||
{% set disabled_fields = ['tenant', 'code'] %}
|
||||
{% set exclude_fields = [] %}
|
||||
{% for field in form %}
|
||||
{{ render_field(field, disabled_fields, exclude_fields) }}
|
||||
{% endfor %}
|
||||
<button type="submit" class="btn btn-primary">Update Partner</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
18
eveai_app/templates/administration/edit_partner_service.html
Normal file
18
eveai_app/templates/administration/edit_partner_service.html
Normal file
@@ -0,0 +1,18 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "macros.html" import render_field %}
|
||||
{% block title %}Register Partner Service{% endblock %}
|
||||
|
||||
{% block content_title %}Register Partner Service{% endblock %}
|
||||
{% block content_description %}Register Partner Service{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
{{ form.hidden_tag() }}
|
||||
{% set disabled_fields = ['type'] %}
|
||||
{% set exclude_fields = [] %}
|
||||
{% for field in form %}
|
||||
{{ render_field(field, disabled_fields, exclude_fields) }}
|
||||
{% endfor %}
|
||||
<button type="submit" class="btn btn-primary">Register Partner Service</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
18
eveai_app/templates/administration/partner_service.html
Normal file
18
eveai_app/templates/administration/partner_service.html
Normal file
@@ -0,0 +1,18 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "macros.html" import render_field %}
|
||||
{% block title %}Register Partner Service{% endblock %}
|
||||
|
||||
{% block content_title %}Register Partner Service{% endblock %}
|
||||
{% block content_description %}Register Partner Service{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
{{ form.hidden_tag() }}
|
||||
{% set disabled_fields = [] %}
|
||||
{% set exclude_fields = [] %}
|
||||
{% for field in form %}
|
||||
{{ render_field(field, disabled_fields, exclude_fields) }}
|
||||
{% endfor %}
|
||||
<button type="submit" class="btn btn-primary">Register Partner Service</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
26
eveai_app/templates/administration/partner_services.html
Normal file
26
eveai_app/templates/administration/partner_services.html
Normal file
@@ -0,0 +1,26 @@
|
||||
{% extends 'base.html' %}
|
||||
{% from 'macros.html' import render_selectable_table, render_pagination %}
|
||||
|
||||
{% block title %}Partner Services{% endblock %}
|
||||
|
||||
{% block content_title %}Partner Services{% endblock %}
|
||||
{% block content_description %}View Partner Services for active Partner{% endblock %}
|
||||
{% block content_class %}<div class="col-xl-12 col-lg-5 col-md-7 mx-auto"></div>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<form method="POST" action="{{ url_for('administration_bp.handle_partner_service_selection') }}" id="partnerServicesForm">
|
||||
{{ render_selectable_table(headers=["Partner Service ID", "Name", "Type"], rows=rows, selectable=True, id="retrieversTable") }}
|
||||
<div class="form-group mt-3 d-flex justify-content-between">
|
||||
<div>
|
||||
<button type="submit" name="action" value="edit_partner_service" class="btn btn-primary" onclick="return validateTableSelection('partnerServicesForm')">Edit Partner Service</button>
|
||||
</div>
|
||||
<button type="submit" name="action" value="create_partner_service" class="btn btn-success">Register Partner Service</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content_footer %}
|
||||
{{ render_pagination(pagination, 'document_bp.retrievers') }}
|
||||
{% endblock %}
|
||||
26
eveai_app/templates/administration/partners.html
Normal file
26
eveai_app/templates/administration/partners.html
Normal file
@@ -0,0 +1,26 @@
|
||||
{% extends 'base.html' %}
|
||||
{% from 'macros.html' import render_selectable_table, render_pagination %}
|
||||
|
||||
{% block title %}Partners{% endblock %}
|
||||
|
||||
{% block content_title %}Partners{% endblock %}
|
||||
{% block content_description %}View Partners{% endblock %}
|
||||
{% block content_class %}<div class="col-xl-12 col-lg-5 col-md-7 mx-auto"></div>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<form method="POST" action="{{ url_for('administration_bp.handle_partner_selection') }}" id="partnersForm">
|
||||
{{ render_selectable_table(headers=["Partner ID", "Name"], rows=rows, selectable=True, id="partnersTable") }}
|
||||
<div class="form-group mt-3 d-flex justify-content-between">
|
||||
<div>
|
||||
<button type="submit" name="action" value="edit_partner" class="btn btn-primary" onclick="return validateTableSelection('partnersForm')">Edit Partner</button>
|
||||
<button type="submit" name="action" value="set_session_partner" class="btn btn-primary" onclick="return validateTableSelection('partnersForm')">Set Session Partner</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content_footer %}
|
||||
{{ render_pagination(pagination, 'document_bp.retrievers') }}
|
||||
{% endblock %}
|
||||
@@ -8,6 +8,7 @@
|
||||
<!-- Trigger action Form -->
|
||||
<form method="POST" action="{{ url_for('administration_bp.handle_trigger_action') }}">
|
||||
<div class="form-group mt-3">
|
||||
<button type="submit" name="action" value="register_partner" class="btn btn-secondary">Register Partner</button>
|
||||
<button type="submit" name="action" value="update_usages" class="btn btn-secondary">Update Usages</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
{{ form.hidden_tag() }}
|
||||
{% set disabled_fields = ['user_name', 'user_email', 'tenant_name'] %}
|
||||
{% set disabled_fields = ['user_name', 'user_email', 'tenant_name', 'partner_name'] %}
|
||||
{% set exclude_fields = [] %}
|
||||
{% for field in form %}
|
||||
{{ render_field(field, disabled_fields, exclude_fields) }}
|
||||
|
||||
@@ -101,6 +101,8 @@
|
||||
{'name': 'Trigger Actions', 'url': '/administration/trigger_actions', 'roles': ['Super User']},
|
||||
{'name': 'Licenses', 'url': '/entitlements/view_licenses', 'roles': ['Super User', 'Tenant Admin']},
|
||||
{'name': 'Usage', 'url': '/entitlements/view_usages', 'roles': ['Super User', 'Tenant Admin']},
|
||||
{'name': 'Partners', 'url': '/administration/partners', 'roles': ['Super User']},
|
||||
{'name': 'Partner Services', 'url': '/administration/partner_services', 'roles': ['Super User']},
|
||||
]) }}
|
||||
{% endif %}
|
||||
{% if current_user.is_authenticated %}
|
||||
@@ -123,6 +125,13 @@
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% if current_user.has_roles('Super User') and 'partner' in session %}
|
||||
<li class="nav-item mt-2">
|
||||
<a href="/session_defaults" class="btn btn-sm bg-gradient-success mb-0">
|
||||
PARTNER {{ session['partner'].get('id', 'None') }}: {{ session['partner'].get('name', 'None') }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
{{ form.hidden_tag() }}
|
||||
{% set disabled_fields = ['name', 'llm_model'] %}
|
||||
{% set disabled_fields = ['name', 'code', 'llm_model'] %}
|
||||
{% set exclude_fields = [] %}
|
||||
{% for field in form %}
|
||||
{{ render_field(field, disabled_fields, exclude_fields) }}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
{{ form.hidden_tag() }}
|
||||
{% set disabled_fields = [] %}
|
||||
{% set disabled_fields = ['code'] %}
|
||||
{% set exclude_fields = [] %}
|
||||
{% for field in form %}
|
||||
{{ render_field(field, disabled_fields, exclude_fields) }}
|
||||
|
||||
@@ -1,7 +1,46 @@
|
||||
from flask import current_app
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms.fields.simple import SubmitField
|
||||
from wtforms.fields.choices import SelectField
|
||||
from wtforms.fields.simple import SubmitField, StringField, BooleanField, TextAreaField
|
||||
from wtforms.validators import DataRequired, Optional, Length
|
||||
|
||||
from common.extensions import cache_manager
|
||||
from common.utils.form_assistants import validate_json
|
||||
from eveai_app.views.dynamic_form_base import DynamicFormBase
|
||||
|
||||
|
||||
class TriggerActionForm(FlaskForm):
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class EditPartnerForm(FlaskForm):
|
||||
tenant = StringField('Tenant', validators=[DataRequired()], render_kw={'readonly': True})
|
||||
code = StringField('Code', description="Referral Code", validators=[DataRequired()], render_kw={'readonly': True})
|
||||
logo_url = StringField('Logo URL', validators=[Optional(), Length(max=255)])
|
||||
active = BooleanField('Active', validators=[DataRequired()], default=True)
|
||||
|
||||
|
||||
class PartnerServiceForm(FlaskForm):
|
||||
name = StringField('Name', validators=[DataRequired(), Length(max=50)])
|
||||
description = TextAreaField('Description', validators=[Optional()])
|
||||
type = SelectField('Partner Service Type', validators=[DataRequired()])
|
||||
active = BooleanField('Active', validators=[DataRequired()], default=True)
|
||||
|
||||
user_metadata = TextAreaField('User Metadata', validators=[Optional(), validate_json])
|
||||
system_metadata = TextAreaField('System Metadata', validators=[Optional(), validate_json])
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
# Dynamically populate the 'type' field
|
||||
types_dict = cache_manager.partner_services_types_cache.get_types()
|
||||
self.type.choices = [(key, value['name']) for key, value in types_dict.items()]
|
||||
|
||||
|
||||
class EditPartnerServiceForm(DynamicFormBase):
|
||||
name = StringField('Name', validators=[DataRequired(), Length(max=50)])
|
||||
description = TextAreaField('Description', validators=[Optional()])
|
||||
type = StringField('Partner Service Type', validators=[DataRequired()], render_kw={'readonly': True})
|
||||
active = BooleanField('Active', validators=[DataRequired()], default=True)
|
||||
|
||||
user_metadata = TextAreaField('User Metadata', validators=[Optional(), validate_json])
|
||||
system_metadata = TextAreaField('System Metadata', validators=[Optional(), validate_json])
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import ast
|
||||
import uuid
|
||||
from datetime import datetime as dt, timezone as tz
|
||||
from flask import request, redirect, flash, render_template, Blueprint, session, current_app, jsonify
|
||||
@@ -5,10 +6,15 @@ from flask_security import hash_password, roles_required, roles_accepted, curren
|
||||
from itsdangerous import URLSafeTimedSerializer
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from common.extensions import db, cache_manager
|
||||
from common.models.user import Partner, Tenant, PartnerService
|
||||
from common.utils.celery_utils import current_celery
|
||||
from common.utils.eveai_exceptions import EveAIException
|
||||
from common.utils.log_utils import format_query_results
|
||||
from common.utils.model_logging_utils import update_logging_information, set_logging_information
|
||||
from common.utils.view_assistants import prepare_table_for_macro, form_validation_failed
|
||||
from common.utils.nginx_utils import prefixed_url_for
|
||||
from .administration_forms import TriggerActionForm
|
||||
from .administration_forms import TriggerActionForm, EditPartnerForm, PartnerServiceForm, EditPartnerServiceForm
|
||||
|
||||
administration_bp = Blueprint('administration_bp', __name__, url_prefix='/administration')
|
||||
|
||||
@@ -35,5 +41,215 @@ def handle_trigger_action():
|
||||
except Exception as e:
|
||||
current_app.logger.error(f"Failed to trigger usage update task: {str(e)}")
|
||||
flash(f'Failed to trigger usage update: {str(e)}', 'danger')
|
||||
case 'register_partner':
|
||||
try:
|
||||
partner_id = register_partner_from_tenant(session['tenant']['id'])
|
||||
return redirect(prefixed_url_for('administration_bp.edit_partner', partner_id=partner_id, ))
|
||||
except EveAIException as e:
|
||||
current_app.logger.error(f'Error registering partner for tenant {session['tenant']['id']}: {str(e)}')
|
||||
flash('Error Registering Partner for Selected Tenant', 'danger')
|
||||
return redirect(prefixed_url_for('user_bp.select_tenant'))
|
||||
|
||||
return redirect(prefixed_url_for('administration_bp.trigger_actions'))
|
||||
|
||||
|
||||
@administration_bp.route('/partner/<int:partner_id>', methods=['GET', 'POST'])
|
||||
@roles_accepted('Super User')
|
||||
def edit_partner(partner_id):
|
||||
partner = Partner.query.get_or_404(partner_id) # This will return a 404 if no partner is found
|
||||
tenant = Tenant.query.get_or_404(partner.tenant_id)
|
||||
form = EditPartnerForm(obj=partner)
|
||||
form.tenant.data = tenant.name
|
||||
|
||||
if form.validate_on_submit():
|
||||
# Populate the user with form data
|
||||
form.populate_obj(partner)
|
||||
update_logging_information(partner, dt.now(tz.utc))
|
||||
db.session.commit()
|
||||
flash('Partner updated successfully.', 'success')
|
||||
return redirect(
|
||||
prefixed_url_for('administration_bp.edit_partner',
|
||||
partner_id=partner.id)) # Assuming there's a user profile view to redirect to
|
||||
else:
|
||||
form_validation_failed(request, form)
|
||||
|
||||
return render_template('administration/edit_partner.html', form=form, partner_id=partner_id)
|
||||
|
||||
|
||||
@administration_bp.route('/partners', methods=['GET', 'POST'])
|
||||
@roles_accepted('Super User')
|
||||
def partners():
|
||||
page = request.args.get('page', 1, type=int)
|
||||
per_page = request.args.get('per_page', 10, type=int)
|
||||
|
||||
query = (db.session.query(
|
||||
Partner.id,
|
||||
Partner.code,
|
||||
Partner.active,
|
||||
Partner.logo_url,
|
||||
# Include all needed Partner columns here
|
||||
Tenant.name.label('name')
|
||||
).join(Tenant, Partner.tenant_id == Tenant.id).order_by(Partner.id))
|
||||
|
||||
current_app.logger.debug(f'{format_query_results(query)}')
|
||||
|
||||
pagination = query.paginate(page=page, per_page=per_page)
|
||||
the_partners = pagination.items
|
||||
|
||||
# prepare table data
|
||||
rows = prepare_table_for_macro(the_partners, [('id', ''), ('name', '')])
|
||||
|
||||
# Render the catalogs in a template
|
||||
return render_template('administration/partners.html', rows=rows, pagination=pagination)
|
||||
|
||||
|
||||
@administration_bp.route('/handle_partner_selection', methods=['POST'])
|
||||
@roles_accepted('Super User')
|
||||
def handle_partner_selection():
|
||||
action = request.form['action']
|
||||
partner_identification = request.form.get('selected_row')
|
||||
partner_id = ast.literal_eval(partner_identification).get('value')
|
||||
partner = Partner.query.get_or_404(partner_id)
|
||||
|
||||
if action == 'set_session_partner':
|
||||
current_app.logger.info(f"Setting session partner: {partner.id}")
|
||||
session['partner'] = partner.to_dict()
|
||||
elif action == 'edit_partner':
|
||||
return redirect(prefixed_url_for('administration_bp.edit_partner', partner_id=partner_id))
|
||||
|
||||
return redirect(prefixed_url_for('administration_bp.partners'))
|
||||
|
||||
|
||||
@administration_bp.route('/partner_service', methods=['GET', 'POST'])
|
||||
@roles_accepted('Super User')
|
||||
def partner_service():
|
||||
form = PartnerServiceForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
partner_id = session.get('partner_id', None)
|
||||
if not partner_id:
|
||||
flash('No partner has been selected. Set partner before adding services.', 'warning')
|
||||
return redirect(prefixed_url_for('administration_bp.partners'))
|
||||
new_partner_service = PartnerService()
|
||||
form.populate_obj(new_partner_service)
|
||||
set_logging_information(new_partner_service, dt.now(tz.utc))
|
||||
new_partner_service.partner_id = partner_id
|
||||
|
||||
try:
|
||||
db.session.add(new_partner_service)
|
||||
db.session.commit()
|
||||
flash('Partner Service successfully added!', 'success')
|
||||
current_app.logger.info(f"Partner Service {new_partner_service.name} added successfully for {partner_id}")
|
||||
# Step 2 of the creation process (depending on type)
|
||||
return redirect(prefixed_url_for('administration_bp.partner_service',
|
||||
partner_service_id=new_partner_service.id))
|
||||
except SQLAlchemyError as e:
|
||||
db.session.rollback()
|
||||
flash(f'Failed to add Partner Service: {str(e)}', 'danger')
|
||||
current_app.logger.error(f"Failed to add Partner Service {new_partner_service.name} "
|
||||
f"for partner {partner_id}. Error: {str(e)}")
|
||||
return render_template('administration/partner_service.html', form=form)
|
||||
|
||||
|
||||
@administration_bp.route('/partner_service/<int:partner_service_id>', methods=['GET', 'POST'])
|
||||
@roles_accepted('Super User')
|
||||
def edit_partner_service(partner_service_id):
|
||||
partner_service = PartnerService.query.get_or_404(partner_service_id)
|
||||
partner_id = session.get('partner_id', None)
|
||||
|
||||
form = EditPartnerServiceForm(obj=partner_service)
|
||||
partner_service_config = cache_manager.partner_services_config_cache.get_config(partner_service.type,
|
||||
partner_service.type_version)
|
||||
configuration_config = partner_service_config.get('configuration')
|
||||
current_app.logger.debug(f"Configuration config for {partner_service.type} {partner_service.type_version}: "
|
||||
f"{configuration_config}")
|
||||
form.add_dynamic_fields("configuration", configuration_config, partner_service.configuration)
|
||||
|
||||
if form.validate_on_submit():
|
||||
form.populate_obj(partner_service)
|
||||
partner_service.configuration = form.get_dynamic_data('configuration')
|
||||
|
||||
# update partner relationship
|
||||
partner_service.partner_id = partner_id
|
||||
|
||||
update_logging_information(partner_service, dt.now(tz.utc))
|
||||
|
||||
try:
|
||||
db.session.add(partner_service)
|
||||
db.session.commit()
|
||||
flash('Partner Service updated successfully.', 'success')
|
||||
current_app.logger.info(f"Partner Service {partner_service.name} updated successfully! ")
|
||||
except SQLAlchemyError as e:
|
||||
db.session.rollback()
|
||||
flash(f'Failed to update Partner Service: {str(e)}', 'danger')
|
||||
current_app.logger.error(f"Failed to update Partner Service {partner_service.id} for partner {partner_id}. "
|
||||
f"Error: {str(e)} ")
|
||||
return render_template('administration/edit_partner_service.html', form=form,
|
||||
partner_service_id=partner_service_id)
|
||||
|
||||
return redirect(prefixed_url_for('administration_bp.partner_services'))
|
||||
else:
|
||||
form_validation_failed(request, form)
|
||||
|
||||
return render_template('administration/edit_partner_service.html', form=form,
|
||||
partner_service_id=partner_service_id)
|
||||
|
||||
|
||||
@administration_bp.route('/partner_services', methods=['GET', 'POST'])
|
||||
@roles_accepted('Super User')
|
||||
def partner_services():
|
||||
page = request.args.get('page', 1, type=int)
|
||||
per_page = request.args.get('per_page', 10, type=int)
|
||||
partner_id = session.get('partner_id', None)
|
||||
if not partner_id:
|
||||
flash('No partner has been selected. Set partner before adding services.', 'warning')
|
||||
return redirect(prefixed_url_for('administration_bp.partners'))
|
||||
|
||||
query = PartnerService.query.filter(PartnerService.partner_id == partner_id)
|
||||
|
||||
pagination = query.paginate(page=page, per_page=per_page)
|
||||
the_partner_services = pagination.items
|
||||
|
||||
# prepare table data
|
||||
rows = prepare_table_for_macro(the_partner_services, [('id', ''), ('name', ''), ('type', '')])
|
||||
|
||||
return render_template('administration/partner_services.html', rows=rows, pagination=pagination)
|
||||
|
||||
|
||||
@administration_bp.route('/handle_partner_service_selection', methods=['POST'])
|
||||
@roles_accepted('Super User')
|
||||
def handle_partner_service_selection():
|
||||
action = request.form['action']
|
||||
if action == 'create_partner_service':
|
||||
return redirect(prefixed_url_for('administration_bp.partner_service'))
|
||||
|
||||
partner_service_identification = request.form.get('selected_row')
|
||||
partner_service_id = ast.literal_eval(partner_service_identification).get('value')
|
||||
|
||||
if action == 'edit_partner_service':
|
||||
return redirect(prefixed_url_for('administration_bp.edit_partner_service',
|
||||
partner_service_id=partner_service_id))
|
||||
|
||||
return redirect(prefixed_url_for('administration_bp.partner_services'))
|
||||
|
||||
|
||||
def register_partner_from_tenant(tenant_id):
|
||||
# check if there is already a partner defined for the tenant
|
||||
partner = Partner.query.filter_by(tenant_id=tenant_id).first()
|
||||
if partner:
|
||||
return partner.id
|
||||
|
||||
try:
|
||||
partner = Partner(
|
||||
tenant_id=tenant_id,
|
||||
code=f"PART-{str(uuid.uuid4())}",
|
||||
)
|
||||
set_logging_information(partner, dt.now(tz.utc))
|
||||
db.session.add(partner)
|
||||
db.session.commit()
|
||||
return partner.id
|
||||
except SQLAlchemyError as e:
|
||||
db.session.rollback()
|
||||
raise EveAIException(f"Failed to register partner for tenant {tenant_id}. Error: {str(e)}")
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@ class SessionDefaultsForm(FlaskForm):
|
||||
tenant_name = StringField('Tenant Name', validators=[DataRequired()])
|
||||
default_language = SelectField('Default Language', choices=[], validators=[DataRequired()])
|
||||
|
||||
# Partner Defaults
|
||||
partner_name = StringField('Partner Name', validators=[DataRequired()])
|
||||
|
||||
# Default Catalog - initialize as a regular SelectField
|
||||
catalog = SelectField('Catalog', choices=[], validators=[Optional()])
|
||||
|
||||
@@ -28,6 +31,10 @@ class SessionDefaultsForm(FlaskForm):
|
||||
self.user_name.data = current_user.user_name
|
||||
self.user_email.data = current_user.email
|
||||
self.tenant_name.data = session.get('tenant').get('name')
|
||||
if session.get('partner', None):
|
||||
self.partner_name.data = session.get('partner').get('name')
|
||||
else:
|
||||
self.partner_name.data = ""
|
||||
self.default_language.choices = [(lang, lang.lower()) for lang in
|
||||
session.get('tenant').get('allowed_languages')]
|
||||
self.default_language.data = session.get('default_language')
|
||||
|
||||
@@ -10,21 +10,13 @@ from wtforms_sqlalchemy.fields import QuerySelectField
|
||||
|
||||
from common.extensions import cache_manager
|
||||
from common.models.document import Catalog
|
||||
from common.utils.form_assistants import validate_json
|
||||
|
||||
from config.type_defs.catalog_types import CATALOG_TYPES
|
||||
from config.type_defs.processor_types import PROCESSOR_TYPES
|
||||
from config.type_defs.retriever_types import RETRIEVER_TYPES
|
||||
from .dynamic_form_base import DynamicFormBase
|
||||
|
||||
|
||||
def validate_json(form, field):
|
||||
if field.data:
|
||||
try:
|
||||
json.loads(field.data)
|
||||
except json.JSONDecodeError:
|
||||
raise ValidationError('Invalid JSON format')
|
||||
|
||||
|
||||
class CatalogForm(FlaskForm):
|
||||
name = StringField('Name', validators=[DataRequired(), Length(max=50)])
|
||||
description = TextAreaField('Description', validators=[Optional()])
|
||||
|
||||
@@ -29,7 +29,6 @@ from common.utils.view_assistants import form_validation_failed, prepare_table_f
|
||||
from .document_list_view import DocumentListView
|
||||
from .document_version_list_view import DocumentVersionListView
|
||||
from config.type_defs.catalog_types import CATALOG_TYPES
|
||||
from config.type_defs.retriever_types import RETRIEVER_TYPES
|
||||
|
||||
document_bp = Blueprint('document_bp', __name__, url_prefix='/document')
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ class DynamicFormBase(FlaskForm):
|
||||
|
||||
# Required validator
|
||||
if field_def.get('required', False):
|
||||
validators_list.append(validators.InputRequired())
|
||||
validators_list.append(validators.DataRequired())
|
||||
else:
|
||||
validators_list.append(validators.Optional())
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ from config.type_defs.service_types import SERVICE_TYPES
|
||||
|
||||
class TenantForm(FlaskForm):
|
||||
name = StringField('Name', validators=[DataRequired(), Length(max=80)])
|
||||
code = StringField('Code', validators=[DataRequired()], render_kw={'readonly': True})
|
||||
type = SelectField('Tenant Type', validators=[Optional()], default='Active')
|
||||
website = StringField('Website', validators=[DataRequired(), Length(max=255)])
|
||||
# language fields
|
||||
@@ -125,3 +126,6 @@ class EditTenantProjectForm(FlaskForm):
|
||||
super().__init__(*args, **kwargs)
|
||||
# Initialize choices for the services field
|
||||
self.services.choices = [(key, value['description']) for key, value in SERVICE_TYPES.items()]
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from itsdangerous import URLSafeTimedSerializer
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
import ast
|
||||
|
||||
from common.models.user import User, Tenant, Role, TenantDomain, TenantProject
|
||||
from common.models.user import User, Tenant, Role, TenantDomain, TenantProject, Partner
|
||||
from common.extensions import db, security, minio_client, simple_encryption
|
||||
from common.utils.security_utils import send_confirmation_email, send_reset_email
|
||||
from config.type_defs.service_types import SERVICE_TYPES
|
||||
@@ -18,6 +18,8 @@ from common.utils.database import Database
|
||||
from common.utils.view_assistants import prepare_table_for_macro, form_validation_failed
|
||||
from common.utils.simple_encryption import generate_api_key
|
||||
from common.utils.nginx_utils import prefixed_url_for
|
||||
from common.utils.eveai_exceptions import EveAIDoublePartner, EveAIException
|
||||
from common.utils.document_utils import set_logging_information, update_logging_information
|
||||
|
||||
user_bp = Blueprint('user_bp', __name__, url_prefix='/user')
|
||||
|
||||
@@ -36,6 +38,10 @@ def log_after_request(response):
|
||||
@roles_required('Super User')
|
||||
def tenant():
|
||||
form = TenantForm()
|
||||
if request.method == 'GET':
|
||||
code = f"TENANT-{str(uuid.uuid4())}"
|
||||
form.code.data = code
|
||||
|
||||
if form.validate_on_submit():
|
||||
# Handle the required attributes
|
||||
new_tenant = Tenant()
|
||||
@@ -244,6 +250,7 @@ def handle_tenant_selection():
|
||||
return redirect(prefixed_url_for('user_bp.tenant_overview'))
|
||||
case 'new_tenant':
|
||||
return redirect(prefixed_url_for('user_bp.tenant'))
|
||||
|
||||
# Add more conditions for other actions
|
||||
return redirect(prefixed_url_for('select_tenant'))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user