- Add functionality to add a default dictionary for configuration fields
- Correct entitlement processing - Remove get_template functionality from ModelVariables, define it directly with LLM model definition in configuration file.
This commit is contained in:
138
eveai_app/templates/entitlements/view_active_license_usage.html
Normal file
138
eveai_app/templates/entitlements/view_active_license_usage.html
Normal file
@@ -0,0 +1,138 @@
|
||||
{% extends 'base.html' %}
|
||||
{% from "macros.html" import render_selectable_table, render_pagination %}
|
||||
|
||||
{% block title %}Active License Usage{% endblock %}
|
||||
|
||||
{% block content_title %}Active License Usage{% endblock %}
|
||||
{% block content_description %}Overview of the current license period usage{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if active_period and active_period.license_usage %}
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header p-3">
|
||||
<h6 class="mb-0">License Information</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p><strong>License ID:</strong> {{ active_period.license.id }}</p>
|
||||
<p><strong>License Name:</strong> {{ active_period.license.name }}</p>
|
||||
<p><strong>Period Nr:</strong> {{ active_period.period_number }}</p>
|
||||
<p><strong>Start Date:</strong> {{ active_period.period_start }}</p>
|
||||
<p><strong>End Date:</strong> {{ active_period.period_end }}</p>
|
||||
<p><strong>Status:</strong> {{ active_period.status.value }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header p-3">
|
||||
<h6 class="mb-0">License Details for Period</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p><strong>Max Storage:</strong> {{ active_period.max_storage_mb }} MB</p>
|
||||
<p><strong>Included Embedding:</strong> {{ active_period.included_embedding_mb }} MB</p>
|
||||
<p><strong>Included Interaction Tokens:</strong> {{ active_period.included_interaction_tokens }}</p>
|
||||
<p><strong>Overage Storage Allowed:</strong> {{ active_period.additional_storage_allowed }}</p>
|
||||
<p><strong>Overage Embedding Allowed:</strong> {{ active_period.additional_embedding_allowed }}</p>
|
||||
<p><strong>Overage Interaction Allowed:</strong> {{ active_period.additional_interaction_allowed }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header p-3">
|
||||
<h6 class="mb-0">Storage Usage</h6>
|
||||
</div>
|
||||
<div class="card-body pt-0">
|
||||
<h2 class="font-weight-bold mt-3
|
||||
{% if usage_data.storage_percent >= 95 %}text-danger
|
||||
{% elif usage_data.storage_percent > 80 %}text-warning
|
||||
{% else %}text-info{% endif %}">
|
||||
{{ usage_data.storage_percent }}%
|
||||
</h2>
|
||||
<div class="progress mt-2">
|
||||
<div class="progress-bar
|
||||
{% if usage_data.storage_percent >= 95 %}bg-danger
|
||||
{% elif usage_data.storage_percent > 80 %}bg-warning
|
||||
{% else %}bg-info{% endif %}"
|
||||
role="progressbar"
|
||||
style="width: {{ usage_data.storage_percent }}%"
|
||||
aria-valuenow="{{ usage_data.storage_percent }}"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100">
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-3">{{ usage_data.storage_used_rounded or 0.0 }} / {{ active_period.max_storage_mb or 0 }} MB</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header p-3">
|
||||
<h6 class="mb-0">Embedding Usage</h6>
|
||||
</div>
|
||||
<div class="card-body pt-0">
|
||||
<h2 class="font-weight-bold mt-3
|
||||
{% if usage_data.embedding_percent >= 95 %}text-danger
|
||||
{% elif usage_data.embedding_percent > 80 %}text-warning
|
||||
{% else %}text-info{% endif %}">
|
||||
{{ usage_data.embedding_percent }}%
|
||||
</h2>
|
||||
<div class="progress mt-2">
|
||||
<div class="progress-bar
|
||||
{% if usage_data.embedding_percent >= 95 %}bg-danger
|
||||
{% elif usage_data.embedding_percent > 80 %}bg-warning
|
||||
{% else %}bg-info{% endif %}"
|
||||
role="progressbar"
|
||||
style="width: {{ usage_data.embedding_percent }}%"
|
||||
aria-valuenow="{{ usage_data.embedding_percent }}"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100">
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-3">{{ usage_data.embedding_used_rounded or 0.0 }} / {{ active_period.included_embedding_mb or 0 }} MB</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header p-3">
|
||||
<h6 class="mb-0">Interaction Usage</h6>
|
||||
</div>
|
||||
<div class="card-body pt-0">
|
||||
<h2 class="font-weight-bold mt-3
|
||||
{% if usage_data.interaction_percent >= 95 %}text-danger
|
||||
{% elif usage_data.interaction_percent > 80 %}text-warning
|
||||
{% else %}text-info{% endif %}">
|
||||
{{ usage_data.interaction_percent }}%
|
||||
</h2>
|
||||
<div class="progress mt-2">
|
||||
<div class="progress-bar
|
||||
{% if usage_data.interaction_percent >= 95 %}bg-danger
|
||||
{% elif usage_data.interaction_percent > 80 %}bg-warning
|
||||
{% else %}bg-info{% endif %}"
|
||||
role="progressbar"
|
||||
style="width: {{ usage_data.interaction_percent }}%"
|
||||
aria-valuenow="{{ usage_data.interaction_percent }}"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100">
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-3">{{ usage_data.interaction_used_rounded or 0.0 }} / {{ active_period.included_interaction_tokens or 0 }} M tokens</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
There's no active license period for this tenant, or no usage data has been recorded yet.
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -114,7 +114,7 @@
|
||||
{'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': 'Active Usage', 'url': '/entitlements/active_usage', 'roles': ['Super User', 'Tenant Admin', 'Partner Admin']},
|
||||
]) }}
|
||||
{% endif %}
|
||||
{% if current_user.is_authenticated %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from datetime import datetime as dt, timezone as tz, timedelta
|
||||
from flask import request, redirect, flash, render_template, Blueprint, session, current_app
|
||||
from flask import request, redirect, flash, render_template, Blueprint, session, current_app, jsonify
|
||||
from flask_security import roles_accepted, current_user
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy import or_, desc
|
||||
@@ -395,4 +395,58 @@ def transition_period_status(license_id, period_id):
|
||||
db.session.rollback()
|
||||
flash(f'Error updating status: {str(e)}', 'danger')
|
||||
|
||||
return redirect(prefixed_url_for('entitlements_bp.view_license_periods', license_id=license_id))
|
||||
return redirect(prefixed_url_for('entitlements_bp.view_license_periods', license_id=license_id))
|
||||
|
||||
|
||||
@entitlements_bp.route('/active_usage')
|
||||
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
|
||||
def active_license_usage():
|
||||
# Retrieve the active license period for the current tenant
|
||||
tenant_id = session.get('tenant', {}).get('id')
|
||||
if not tenant_id:
|
||||
flash('No active or pending license period found for this tenant', 'warning')
|
||||
return redirect(prefixed_url_for('user_bp.select_tenant'))
|
||||
|
||||
active_period = LicensePeriod.query \
|
||||
.join(License) \
|
||||
.filter(
|
||||
License.tenant_id == tenant_id,
|
||||
LicensePeriod.status.in_([PeriodStatus.ACTIVE, PeriodStatus.PENDING])
|
||||
).first()
|
||||
|
||||
if not active_period:
|
||||
flash('Geen actieve of pending licentieperiode gevonden voor deze tenant', 'warning')
|
||||
return render_template('entitlements/view_active_license_usage.html', active_period=None)
|
||||
|
||||
# Bereken de percentages voor gebruik
|
||||
usage_data = {}
|
||||
if active_period.license_usage:
|
||||
# Storage percentage
|
||||
if active_period.max_storage_mb > 0:
|
||||
storage_used = active_period.license_usage.storage_mb_used or 0.0
|
||||
usage_data['storage_used_rounded'] = round(storage_used, 2)
|
||||
usage_data['storage_percent'] = round(storage_used / active_period.max_storage_mb * 100, 2)
|
||||
else:
|
||||
usage_data['storage_percent'] = 0.0
|
||||
|
||||
# Embedding percentage
|
||||
if active_period.included_embedding_mb > 0:
|
||||
embedding_used = active_period.license_usage.embedding_mb_used or 0.0
|
||||
usage_data['embedding_used_rounded'] = round(embedding_used, 2)
|
||||
usage_data['embedding_percent'] = round(embedding_used / active_period.included_embedding_mb * 100, 2)
|
||||
else:
|
||||
usage_data['embedding_percent'] = 0.0
|
||||
|
||||
# Interaction tokens percentage
|
||||
if active_period.included_interaction_tokens > 0:
|
||||
interaction_used = active_period.license_usage.interaction_total_tokens_used / 1_000_000 or 0.0
|
||||
usage_data['interaction_used_rounded'] = round(interaction_used, 2)
|
||||
usage_data['interaction_percent'] = (
|
||||
round(interaction_used / active_period.included_interaction_tokens * 100, 2))
|
||||
else:
|
||||
usage_data['interaction_percent'] = 0
|
||||
|
||||
return render_template('entitlements/view_active_license_usage.html',
|
||||
active_period=active_period,
|
||||
usage_data=usage_data)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user