- Partner model additions

- menu changes to allow for partners
- partner views and forms now in partner_forms.py and partner_views.py
- Introduction of services layer
- Allow all configuration to handle partner configurations, and adaptation of caching to allow for this
This commit is contained in:
Josako
2025-05-02 13:10:59 +02:00
parent 9652d0bff9
commit 6ef025363d
72 changed files with 1342 additions and 228 deletions

View File

@@ -11,7 +11,7 @@
{{ form.hidden_tag() }}
{% set main_fields = ['start_date', 'end_date', 'currency', 'yearly_payment', 'basic_fee'] %}
{% for field in form %}
{{ render_included_field(field, disabled_fields=['currency'], include_fields=main_fields) }}
{{ render_included_field(field, readonly_fields=ext_readonly_fields + ['currency'], include_fields=main_fields) }}
{% endfor %}
<!-- Nav Tabs -->
<div class="row mt-5">
@@ -40,21 +40,21 @@
<div class="tab-pane fade show active" id="storage-tab" role="tabpanel">
{% set storage_fields = ['max_storage_tokens', 'additional_storage_token_price', 'additional_storage_bucket'] %}
{% for field in form %}
{{ render_included_field(field, disabled_fields=[], include_fields=storage_fields) }}
{{ render_included_field(field, readonly_fields=ext_readonly_fields, include_fields=storage_fields) }}
{% endfor %}
</div>
<!-- Embedding Tab -->
<div class="tab-pane fade" id="embedding-tab" role="tabpanel">
{% set embedding_fields = ['included_embedding_tokens', 'additional_embedding_token_price', 'additional_embedding_bucket'] %}
{% for field in form %}
{{ render_included_field(field, disabled_fields=[], include_fields=embedding_fields) }}
{{ render_included_field(field, readonly_fields=ext_readonly_fields, include_fields=embedding_fields) }}
{% endfor %}
</div>
<!-- Interaction Tab -->
<div class="tab-pane fade" id="interaction-tab" role="tabpanel">
{% set interaction_fields = ['included_interaction_tokens', 'additional_interaction_token_price', 'additional_interaction_bucket'] %}
{% for field in form %}
{{ render_included_field(field, disabled_fields=[], include_fields=interaction_fields) }}
{{ render_included_field(field, readonly_fields=ext_readonly_fields, include_fields=interaction_fields) }}
{% endfor %}
</div>
</div>

View File

@@ -11,7 +11,7 @@
{{ form.hidden_tag() }}
{% set main_fields = ['start_date', 'end_date', 'currency', 'yearly_payment', 'basic_fee'] %}
{% for field in form %}
{{ render_included_field(field, disabled_fields=ext_disabled_fields + ['currency'], include_fields=main_fields) }}
{{ render_included_field(field, readonly_fields=ext_readonly_fields + ['currency'], include_fields=main_fields) }}
{% endfor %}
<!-- Nav Tabs -->
<div class="row mt-5">
@@ -40,21 +40,21 @@
<div class="tab-pane fade show active" id="storage-tab" role="tabpanel">
{% set storage_fields = ['max_storage_mb', 'additional_storage_price', 'additional_storage_bucket'] %}
{% for field in form %}
{{ render_included_field(field, disabled_fields=ext_disabled_fields, include_fields=storage_fields) }}
{{ render_included_field(field, readonly_fields=ext_readonly_fields, include_fields=storage_fields) }}
{% endfor %}
</div>
<!-- Embedding Tab -->
<div class="tab-pane fade" id="embedding-tab" role="tabpanel">
{% set embedding_fields = ['included_embedding_mb', 'additional_embedding_price', 'additional_embedding_bucket', 'overage_embedding'] %}
{% for field in form %}
{{ render_included_field(field, disabled_fields=ext_disabled_fields, include_fields=embedding_fields) }}
{{ render_included_field(field, readonly_fields=ext_readonly_fields, include_fields=embedding_fields) }}
{% endfor %}
</div>
<!-- Interaction Tab -->
<div class="tab-pane fade" id="interaction-tab" role="tabpanel">
{% set interaction_fields = ['included_interaction_tokens', 'additional_interaction_token_price', 'additional_interaction_bucket', 'overage_interaction'] %}
{% for field in form %}
{{ render_included_field(field, disabled_fields=ext_disabled_fields, include_fields=interaction_fields) }}
{{ render_included_field(field, readonly_fields=ext_readonly_fields, include_fields=interaction_fields) }}
{% endfor %}
</div>
</div>

View File

@@ -10,10 +10,19 @@
{{ render_selectable_table(headers=["ID", "Name", "Version", "Start Date", "End Date"], rows=rows, selectable=True, id="licenseTierTable") }}
<div class="form-group mt-3 d-flex justify-content-between">
<div>
<button type="submit" name="action" value="edit_license_tier" class="btn btn-primary" onclick="return validateTableSelection('licenseTiersForm')">Edit License Tier</button>
<button type="submit" name="action" value="create_license_for_tenant" class="btn btn-secondary" onclick="return validateTableSelection('licenseTiersForm')">Create License for Current Tenant</button>
{% if current_user.has_role('Super User') %}
<button type="submit" name="action" value="edit_license_tier" class="btn btn-primary" onclick="return validateTableSelection('licenseTiersForm')">Edit License Tier</button>
{% endif %}
{% if current_user.has_role('Super User') or (current_user.has_role('Partner Admin') and can_assign_license) %}
<button type="submit" name="action" value="create_license_for_tenant" class="btn btn-secondary" onclick="return validateTableSelection('licenseTiersForm')">Create Tenant License</button>
{% endif %}
{% if current_user.has_role('Super User') %}
<button type="submit" name="action" value="associate_license_tier_to_partner" class="btn btn-secondary" onclick="return validateTableSelection('licenseTiersForm')">Associate to Partner</button>
{% endif %}
</div>
<button type="submit" name="action" value="create_license_tier" class="btn btn-success">Register License Tier</button>
{% if current_user.has_role('Super User') %}
<button type="submit" name="action" value="create_license_tier" class="btn btn-success">Register License Tier</button>
{% endif %}
</div>
</form>

View File

@@ -1,8 +1,8 @@
{% macro render_field_content(field, disabled=False, class='') %}
{% macro render_field_content(field, disabled=False, readonly=False, class='') %}
{% if field.type == 'BooleanField' %}
<div class="form-group">
<div class="form-check form-switch">
{{ field(class="form-check-input " + class, disabled=disabled, required=False) }}
{{ field(class="form-check-input " + class, disabled=disabled, readonly=readonly, required=False) }}
{% if field.description %}
{{ field.label(class="form-check-label",
**{'data-bs-toggle': 'tooltip',
@@ -57,11 +57,11 @@
{% if field.type == 'TextAreaField' and 'json-editor' in class %}
<div id="{{ field.id }}-editor" class="json-editor-container"></div>
{{ field(class="form-control d-none " + class, disabled=disabled) }}
{{ field(class="form-control d-none " + class, disabled=disabled, readonly=readonly) }}
{% elif field.type == 'SelectField' %}
{{ field(class="form-control form-select " + class, disabled=disabled) }}
{{ field(class="form-control form-select " + class, disabled=disabled, readonly=readonly) }}
{% else %}
{{ field(class="form-control " + class, disabled=disabled) }}
{{ field(class="form-control " + class, disabled=disabled, readonly=readonly) }}
{% endif %}
{% if field.errors %}
@@ -76,21 +76,23 @@
{% endmacro %}
{% macro render_field(field, disabled_fields=[], exclude_fields=[], class='') %}
{% macro render_field(field, disabled_fields=[], readonly_fields=[], exclude_fields=[], class='') %}
<!-- Debug info -->
<!-- Field name: {{ field.name }}, Field type: {{ field.__class__.__name__ }} -->
{% set disabled = field.name in disabled_fields %}
{% set readonly = field.name in readonly_fields %}
{% set exclude_fields = exclude_fields + ['csrf_token', 'submit'] %}
{% if field.name not in exclude_fields %}
{{ render_field_content(field, disabled, class) }}
{{ render_field_content(field, disabled, readonly, class) }}
{% endif %}
{% endmacro %}
{% macro render_included_field(field, disabled_fields=[], include_fields=[], class='') %}
{% macro render_included_field(field, disabled_fields=[], readonly_fields=[], include_fields=[], class='') %}
{% set disabled = field.name in disabled_fields %}
{% set readonly = field.name in readonly_fields %}
{% if field.name in include_fields %}
{{ render_field_content(field, disabled, class) }}
{{ render_field_content(field, disabled, readonly, class) }}
{% endif %}
{% endmacro %}

View File

@@ -68,7 +68,7 @@
<div class="collapse navbar-collapse w-100 pt-3 pb-2 py-lg-0" id="navigation">
<ul class="navbar-nav navbar-nav-hover mx-auto">
{% if current_user.is_authenticated %}
{{ dropdown('Tenant Configuration', 'source_environment', [
{{ dropdown('Tenants', 'source_environment', [
{'name': 'Tenants', 'url': '/user/select_tenant', 'roles': ['Super User', 'Partner Admin']},
{'name': 'Tenant Overview', 'url': '/user/tenant_overview', 'roles': ['Super User', 'Partner Admin', 'Tenant Admin']},
{'name': 'Edit Tenant', 'url': '/user/tenant/' ~ session['tenant'].get('id'), 'roles': ['Super User', 'Partner Admin', 'Tenant Admin']},
@@ -78,7 +78,14 @@
]) }}
{% endif %}
{% if current_user.is_authenticated %}
{{ dropdown('Document Mgmt', 'note_stack', [
{{ dropdown('Partners', 'partner_exchange', [
{'name': 'Partners', 'url': '/partner/partners', 'roles': ['Super User']},
{'name': 'Partner Services', 'url': '/partner/partner_services', 'roles': ['Super User']},
{'name': 'Edit Partner', 'url': '/partner/partner/' ~ session['partner'].get('id'), 'roles': ['Super User', 'Partner Admin']},
]) }}
{% endif %}
{% if current_user.is_authenticated %}
{{ dropdown('Documents', 'note_stack', [
{'name': 'Catalogs', 'url': '/document/catalogs', 'roles': ['Super User', 'Partner Admin', 'Tenant Admin']},
{'name': 'Processors', 'url': '/document/processors', 'roles': ['Super User', 'Partner Admin', 'Tenant Admin']},
{'name': 'Retrievers', 'url': '/document/retrievers', 'roles': ['Super User', 'Partner Admin', 'Tenant Admin']},
@@ -96,13 +103,11 @@
]) }}
{% endif %}
{% if current_user.is_authenticated %}
{{ dropdown('Administration', 'settings', [
{{ dropdown('Entitlements', 'settings', [
{'name': 'License Tiers', 'url': '/entitlements/view_license_tiers', 'roles': ['Super User', 'Partner Admin']},
{'name': 'Trigger Actions', 'url': '/administration/trigger_actions', 'roles': ['Super User']},
{'name': 'Licenses', 'url': '/entitlements/view_licenses', 'roles': ['Super User', 'Tenant Admin', 'Partner Admin']},
{'name': 'Usage', 'url': '/entitlements/view_usages', 'roles': ['Super User', 'Tenant Admin', 'Partner 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 %}

View File

@@ -9,11 +9,12 @@
{% block content %}
<div class="container">
<form method="POST" action="{{ url_for('administration_bp.handle_partner_service_selection') }}" id="partnerServicesForm">
<form method="POST" action="{{ url_for('partner_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>
<button type="submit" name="action" value="add_partner_service_for_tenant" class="btn btn-primary" onclick="return validateTableSelection('partnerServicesForm')">Add Partner Service for Tenant</button>
</div>
<button type="submit" name="action" value="create_partner_service" class="btn btn-success">Register Partner Service</button>
</div>

View File

@@ -9,7 +9,7 @@
{% block content %}
<div class="container">
<form method="POST" action="{{ url_for('administration_bp.handle_partner_selection') }}" id="partnersForm">
<form method="POST" action="{{ url_for('partner_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>

View File

@@ -6,7 +6,7 @@
{% block content %}
<!-- Trigger action Form -->
<form method="POST" action="{{ url_for('administration_bp.handle_trigger_action') }}">
<form method="POST" action="{{ url_for('partner_bp.handle_trigger_action') }}">
<div class="form-group mt-3">
<button type="submit" name="action" value="update_usages" class="btn btn-secondary">Update Usages</button>
</div>