Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cc699506d3 | |||
| 84da2eb489 | |||
| a9a61c98f5 | |||
| 4678022c7b | |||
| ca2d2e6587 |
Binary file not shown.
@@ -25,6 +25,13 @@ services:
|
|||||||
- GIT_COMMIT=${GIT_COMMIT:-unknown}
|
- GIT_COMMIT=${GIT_COMMIT:-unknown}
|
||||||
- GIT_BRANCH=${GIT_BRANCH:-unknown}
|
- GIT_BRANCH=${GIT_BRANCH:-unknown}
|
||||||
- DEPLOYED_AT=${DEPLOYED_AT:-unknown}
|
- DEPLOYED_AT=${DEPLOYED_AT:-unknown}
|
||||||
|
- PRICING_TIER_ID=${PRICING_TIER_ID:-0}
|
||||||
|
- PRICING_TIER_NAME=${PRICING_TIER_NAME:-Unknown}
|
||||||
|
- ROOM_QUOTA=${ROOM_QUOTA:-0}
|
||||||
|
- CONVERSATION_QUOTA=${CONVERSATION_QUOTA:-0}
|
||||||
|
- STORAGE_QUOTA_GB=${STORAGE_QUOTA_GB:-0}
|
||||||
|
- MANAGER_QUOTA=${MANAGER_QUOTA:-0}
|
||||||
|
- ADMIN_QUOTA=${ADMIN_QUOTA:-0}
|
||||||
volumes:
|
volumes:
|
||||||
- docupulse_uploads:/app/uploads
|
- docupulse_uploads:/app/uploads
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
"""add portainer stack fields to instances
|
||||||
|
|
||||||
|
Revision ID: 9206bf87bb8e
|
||||||
|
Revises: add_quota_fields
|
||||||
|
Create Date: 2025-06-24 14:02:17.375785
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import text
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '9206bf87bb8e'
|
||||||
|
down_revision = 'add_quota_fields'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
conn = op.get_bind()
|
||||||
|
|
||||||
|
# Check if columns already exist
|
||||||
|
result = conn.execute(text("""
|
||||||
|
SELECT column_name
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name = 'instances'
|
||||||
|
AND column_name IN ('portainer_stack_id', 'portainer_stack_name')
|
||||||
|
"""))
|
||||||
|
existing_columns = [row[0] for row in result.fetchall()]
|
||||||
|
|
||||||
|
# Add portainer stack columns if they don't exist
|
||||||
|
with op.batch_alter_table('instances', schema=None) as batch_op:
|
||||||
|
if 'portainer_stack_id' not in existing_columns:
|
||||||
|
batch_op.add_column(sa.Column('portainer_stack_id', sa.String(length=100), nullable=True))
|
||||||
|
if 'portainer_stack_name' not in existing_columns:
|
||||||
|
batch_op.add_column(sa.Column('portainer_stack_name', sa.String(length=100), nullable=True))
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('instances', schema=None) as batch_op:
|
||||||
|
batch_op.drop_column('portainer_stack_name')
|
||||||
|
batch_op.drop_column('portainer_stack_id')
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
@@ -20,10 +20,20 @@ def upgrade():
|
|||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_table('email_template')
|
op.drop_table('email_template')
|
||||||
op.drop_table('notification')
|
op.drop_table('notification')
|
||||||
|
|
||||||
|
# Check if columns already exist before adding them
|
||||||
|
connection = op.get_bind()
|
||||||
|
inspector = sa.inspect(connection)
|
||||||
|
existing_columns = [col['name'] for col in inspector.get_columns('instances')]
|
||||||
|
|
||||||
with op.batch_alter_table('instances', schema=None) as batch_op:
|
with op.batch_alter_table('instances', schema=None) as batch_op:
|
||||||
|
if 'deployed_version' not in existing_columns:
|
||||||
batch_op.add_column(sa.Column('deployed_version', sa.String(length=50), nullable=True))
|
batch_op.add_column(sa.Column('deployed_version', sa.String(length=50), nullable=True))
|
||||||
|
if 'deployed_branch' not in existing_columns:
|
||||||
batch_op.add_column(sa.Column('deployed_branch', sa.String(length=100), nullable=True))
|
batch_op.add_column(sa.Column('deployed_branch', sa.String(length=100), nullable=True))
|
||||||
|
if 'latest_version' not in existing_columns:
|
||||||
batch_op.add_column(sa.Column('latest_version', sa.String(length=50), nullable=True))
|
batch_op.add_column(sa.Column('latest_version', sa.String(length=50), nullable=True))
|
||||||
|
if 'version_checked_at' not in existing_columns:
|
||||||
batch_op.add_column(sa.Column('version_checked_at', sa.DateTime(), nullable=True))
|
batch_op.add_column(sa.Column('version_checked_at', sa.DateTime(), nullable=True))
|
||||||
|
|
||||||
with op.batch_alter_table('room_file', schema=None) as batch_op:
|
with op.batch_alter_table('room_file', schema=None) as batch_op:
|
||||||
@@ -37,10 +47,19 @@ def downgrade():
|
|||||||
with op.batch_alter_table('room_file', schema=None) as batch_op:
|
with op.batch_alter_table('room_file', schema=None) as batch_op:
|
||||||
batch_op.create_foreign_key(batch_op.f('fk_room_file_deleted_by_user'), 'user', ['deleted_by'], ['id'])
|
batch_op.create_foreign_key(batch_op.f('fk_room_file_deleted_by_user'), 'user', ['deleted_by'], ['id'])
|
||||||
|
|
||||||
|
# Check if columns exist before dropping them
|
||||||
|
connection = op.get_bind()
|
||||||
|
inspector = sa.inspect(connection)
|
||||||
|
existing_columns = [col['name'] for col in inspector.get_columns('instances')]
|
||||||
|
|
||||||
with op.batch_alter_table('instances', schema=None) as batch_op:
|
with op.batch_alter_table('instances', schema=None) as batch_op:
|
||||||
|
if 'version_checked_at' in existing_columns:
|
||||||
batch_op.drop_column('version_checked_at')
|
batch_op.drop_column('version_checked_at')
|
||||||
|
if 'latest_version' in existing_columns:
|
||||||
batch_op.drop_column('latest_version')
|
batch_op.drop_column('latest_version')
|
||||||
|
if 'deployed_branch' in existing_columns:
|
||||||
batch_op.drop_column('deployed_branch')
|
batch_op.drop_column('deployed_branch')
|
||||||
|
if 'deployed_version' in existing_columns:
|
||||||
batch_op.drop_column('deployed_version')
|
batch_op.drop_column('deployed_version')
|
||||||
|
|
||||||
op.create_table('notification',
|
op.create_table('notification',
|
||||||
|
|||||||
@@ -528,6 +528,9 @@ class Instance(db.Model):
|
|||||||
status = db.Column(db.String(20), nullable=False, default='inactive')
|
status = db.Column(db.String(20), nullable=False, default='inactive')
|
||||||
status_details = db.Column(db.Text, nullable=True)
|
status_details = db.Column(db.Text, nullable=True)
|
||||||
connection_token = db.Column(db.String(64), unique=True, nullable=True)
|
connection_token = db.Column(db.String(64), unique=True, nullable=True)
|
||||||
|
# Portainer integration fields
|
||||||
|
portainer_stack_id = db.Column(db.String(100), nullable=True) # Portainer stack ID
|
||||||
|
portainer_stack_name = db.Column(db.String(100), nullable=True) # Portainer stack name
|
||||||
# Version tracking fields
|
# Version tracking fields
|
||||||
deployed_version = db.Column(db.String(50), nullable=True) # Current deployed version (commit hash or tag)
|
deployed_version = db.Column(db.String(50), nullable=True) # Current deployed version (commit hash or tag)
|
||||||
deployed_branch = db.Column(db.String(100), nullable=True) # Branch that was deployed
|
deployed_branch = db.Column(db.String(100), nullable=True) # Branch that was deployed
|
||||||
|
|||||||
@@ -1090,13 +1090,9 @@ def save_instance():
|
|||||||
|
|
||||||
if existing_instance:
|
if existing_instance:
|
||||||
# Update existing instance
|
# Update existing instance
|
||||||
existing_instance.port = data['port']
|
existing_instance.portainer_stack_id = data['stack_id']
|
||||||
existing_instance.domains = data['domains']
|
existing_instance.portainer_stack_name = data['stack_name']
|
||||||
existing_instance.stack_id = data['stack_id']
|
|
||||||
existing_instance.stack_name = data['stack_name']
|
|
||||||
existing_instance.status = data['status']
|
existing_instance.status = data['status']
|
||||||
existing_instance.repository = data['repository']
|
|
||||||
existing_instance.branch = data['branch']
|
|
||||||
existing_instance.deployed_version = data.get('deployed_version', 'unknown')
|
existing_instance.deployed_version = data.get('deployed_version', 'unknown')
|
||||||
existing_instance.deployed_branch = data.get('deployed_branch', data['branch'])
|
existing_instance.deployed_branch = data.get('deployed_branch', data['branch'])
|
||||||
existing_instance.version_checked_at = datetime.utcnow()
|
existing_instance.version_checked_at = datetime.utcnow()
|
||||||
@@ -1107,13 +1103,9 @@ def save_instance():
|
|||||||
'message': 'Instance data updated successfully',
|
'message': 'Instance data updated successfully',
|
||||||
'data': {
|
'data': {
|
||||||
'name': existing_instance.name,
|
'name': existing_instance.name,
|
||||||
'port': existing_instance.port,
|
'portainer_stack_id': existing_instance.portainer_stack_id,
|
||||||
'domains': existing_instance.domains,
|
'portainer_stack_name': existing_instance.portainer_stack_name,
|
||||||
'stack_id': existing_instance.stack_id,
|
|
||||||
'stack_name': existing_instance.stack_name,
|
|
||||||
'status': existing_instance.status,
|
'status': existing_instance.status,
|
||||||
'repository': existing_instance.repository,
|
|
||||||
'branch': existing_instance.branch,
|
|
||||||
'deployed_version': existing_instance.deployed_version,
|
'deployed_version': existing_instance.deployed_version,
|
||||||
'deployed_branch': existing_instance.deployed_branch
|
'deployed_branch': existing_instance.deployed_branch
|
||||||
}
|
}
|
||||||
@@ -1126,14 +1118,11 @@ def save_instance():
|
|||||||
rooms_count=0,
|
rooms_count=0,
|
||||||
conversations_count=0,
|
conversations_count=0,
|
||||||
data_size=0.0,
|
data_size=0.0,
|
||||||
payment_plan='Basic',
|
payment_plan=data.get('payment_plan', 'Basic'),
|
||||||
main_url=f"https://{data['domains'][0]}" if data['domains'] else f"http://localhost:{data['port']}",
|
main_url=f"https://{data['domains'][0]}" if data['domains'] else f"http://localhost:{data['port']}",
|
||||||
status=data['status'],
|
status=data['status'],
|
||||||
port=data['port'],
|
portainer_stack_id=data['stack_id'],
|
||||||
stack_id=data['stack_id'],
|
portainer_stack_name=data['stack_name'],
|
||||||
stack_name=data['stack_name'],
|
|
||||||
repository=data['repository'],
|
|
||||||
branch=data['branch'],
|
|
||||||
deployed_version=data.get('deployed_version', 'unknown'),
|
deployed_version=data.get('deployed_version', 'unknown'),
|
||||||
deployed_branch=data.get('deployed_branch', data['branch'])
|
deployed_branch=data.get('deployed_branch', data['branch'])
|
||||||
)
|
)
|
||||||
@@ -1145,13 +1134,9 @@ def save_instance():
|
|||||||
'message': 'Instance data saved successfully',
|
'message': 'Instance data saved successfully',
|
||||||
'data': {
|
'data': {
|
||||||
'name': instance.name,
|
'name': instance.name,
|
||||||
'port': instance.port,
|
'portainer_stack_id': instance.portainer_stack_id,
|
||||||
'domains': instance.domains,
|
'portainer_stack_name': instance.portainer_stack_name,
|
||||||
'stack_id': instance.stack_id,
|
|
||||||
'stack_name': instance.stack_name,
|
|
||||||
'status': instance.status,
|
'status': instance.status,
|
||||||
'repository': instance.repository,
|
|
||||||
'branch': instance.branch,
|
|
||||||
'deployed_version': instance.deployed_version,
|
'deployed_version': instance.deployed_version,
|
||||||
'deployed_branch': instance.deployed_branch
|
'deployed_branch': instance.deployed_branch
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -593,6 +593,9 @@ async function startLaunch(data) {
|
|||||||
// Save instance data
|
// Save instance data
|
||||||
await updateStep(10, 'Saving Instance Data', 'Storing instance information...');
|
await updateStep(10, 'Saving Instance Data', 'Storing instance information...');
|
||||||
try {
|
try {
|
||||||
|
// Get the launch data from sessionStorage to access pricing tier info
|
||||||
|
const launchData = JSON.parse(sessionStorage.getItem('instanceLaunchData') || '{}');
|
||||||
|
|
||||||
const instanceData = {
|
const instanceData = {
|
||||||
name: data.instanceName,
|
name: data.instanceName,
|
||||||
port: data.port,
|
port: data.port,
|
||||||
@@ -603,7 +606,8 @@ async function startLaunch(data) {
|
|||||||
repository: data.repository,
|
repository: data.repository,
|
||||||
branch: data.branch,
|
branch: data.branch,
|
||||||
deployed_version: dockerComposeResult.latest_tag || dockerComposeResult.commit_hash || 'unknown',
|
deployed_version: dockerComposeResult.latest_tag || dockerComposeResult.commit_hash || 'unknown',
|
||||||
deployed_branch: data.branch
|
deployed_branch: data.branch,
|
||||||
|
payment_plan: launchData.pricingTier?.name || 'Basic' // Use the selected pricing tier name
|
||||||
};
|
};
|
||||||
console.log('Saving instance data:', instanceData);
|
console.log('Saving instance data:', instanceData);
|
||||||
const saveResult = await saveInstanceData(instanceData);
|
const saveResult = await saveInstanceData(instanceData);
|
||||||
@@ -2046,28 +2050,8 @@ async function saveInstanceData(instanceData) {
|
|||||||
|
|
||||||
if (existingInstance) {
|
if (existingInstance) {
|
||||||
console.log('Instance already exists:', instanceData.port);
|
console.log('Instance already exists:', instanceData.port);
|
||||||
return {
|
// Update existing instance with new data
|
||||||
success: true,
|
const updateResponse = await fetch('/api/admin/save-instance', {
|
||||||
data: {
|
|
||||||
name: instanceData.port,
|
|
||||||
company: 'loading...',
|
|
||||||
rooms_count: 0,
|
|
||||||
conversations_count: 0,
|
|
||||||
data_size: 0.0,
|
|
||||||
payment_plan: 'Basic',
|
|
||||||
main_url: `https://${instanceData.domains[0]}`,
|
|
||||||
status: 'inactive',
|
|
||||||
port: instanceData.port,
|
|
||||||
stack_id: instanceData.stack_id || '', // Use empty string if null
|
|
||||||
stack_name: instanceData.stack_name,
|
|
||||||
repository: instanceData.repository,
|
|
||||||
branch: instanceData.branch
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// If instance doesn't exist, create it
|
|
||||||
const response = await fetch('/instances/add', {
|
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -2075,18 +2059,53 @@ async function saveInstanceData(instanceData) {
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: instanceData.port,
|
name: instanceData.port,
|
||||||
company: 'loading...',
|
|
||||||
rooms_count: 0,
|
|
||||||
conversations_count: 0,
|
|
||||||
data_size: 0.0,
|
|
||||||
payment_plan: 'Basic',
|
|
||||||
main_url: `https://${instanceData.domains[0]}`,
|
|
||||||
status: 'inactive',
|
|
||||||
port: instanceData.port,
|
port: instanceData.port,
|
||||||
stack_id: instanceData.stack_id || '', // Use empty string if null
|
domains: instanceData.domains,
|
||||||
|
stack_id: instanceData.stack_id || '',
|
||||||
stack_name: instanceData.stack_name,
|
stack_name: instanceData.stack_name,
|
||||||
|
status: instanceData.status,
|
||||||
repository: instanceData.repository,
|
repository: instanceData.repository,
|
||||||
branch: instanceData.branch
|
branch: instanceData.branch,
|
||||||
|
deployed_version: instanceData.deployed_version,
|
||||||
|
deployed_branch: instanceData.deployed_branch,
|
||||||
|
payment_plan: instanceData.payment_plan || 'Basic'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updateResponse.ok) {
|
||||||
|
const errorText = await updateResponse.text();
|
||||||
|
console.error('Error updating instance:', errorText);
|
||||||
|
throw new Error(`Failed to update instance data: ${updateResponse.status} ${updateResponse.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateResult = await updateResponse.json();
|
||||||
|
console.log('Instance updated:', updateResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: updateResult.data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// If instance doesn't exist, create it
|
||||||
|
const response = await fetch('/api/admin/save-instance', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: instanceData.port,
|
||||||
|
port: instanceData.port,
|
||||||
|
domains: instanceData.domains,
|
||||||
|
stack_id: instanceData.stack_id || '',
|
||||||
|
stack_name: instanceData.stack_name,
|
||||||
|
status: instanceData.status,
|
||||||
|
repository: instanceData.repository,
|
||||||
|
branch: instanceData.branch,
|
||||||
|
deployed_version: instanceData.deployed_version,
|
||||||
|
deployed_branch: instanceData.deployed_branch,
|
||||||
|
payment_plan: instanceData.payment_plan || 'Basic'
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,21 @@
|
|||||||
<div class="company-value" id="instance-payment-plan-value">Loading...</div>
|
<div class="company-value" id="instance-payment-plan-value">Loading...</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<div class="d-flex">
|
||||||
|
<div class="text-muted me-2" style="min-width: 120px;">Portainer Stack:</div>
|
||||||
|
<div class="company-value">
|
||||||
|
{% if instance.portainer_stack_name %}
|
||||||
|
<span class="badge bg-primary">{{ instance.portainer_stack_name }}</span>
|
||||||
|
{% if instance.portainer_stack_id %}
|
||||||
|
<small class="text-muted d-block mt-1">ID: {{ instance.portainer_stack_id }}</small>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<span class="text-muted">Not set</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h5 class="mb-3">Contact Information</h5>
|
<h5 class="mb-3">Contact Information</h5>
|
||||||
|
|||||||
@@ -179,6 +179,7 @@
|
|||||||
<th>Main URL</th>
|
<th>Main URL</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th>Version</th>
|
<th>Version</th>
|
||||||
|
<th>Portainer Stack</th>
|
||||||
<th>Connection Token</th>
|
<th>Connection Token</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -191,7 +192,7 @@
|
|||||||
<td>{{ instance.rooms_count }}</td>
|
<td>{{ instance.rooms_count }}</td>
|
||||||
<td>{{ instance.conversations_count }}</td>
|
<td>{{ instance.conversations_count }}</td>
|
||||||
<td>{{ "%.1f"|format(instance.data_size) }} GB</td>
|
<td>{{ "%.1f"|format(instance.data_size) }} GB</td>
|
||||||
<td>{{ instance.payment_plan }}</td>
|
<td id="payment-plan-{{ instance.id }}">{{ instance.payment_plan }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ instance.main_url }}"
|
<a href="{{ instance.main_url }}"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@@ -220,6 +221,16 @@
|
|||||||
<span class="badge bg-secondary version-badge">unknown</span>
|
<span class="badge bg-secondary version-badge">unknown</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if instance.portainer_stack_name %}
|
||||||
|
<span class="badge bg-primary" data-bs-toggle="tooltip"
|
||||||
|
title="Stack ID: {{ instance.portainer_stack_id or 'N/A' }}">
|
||||||
|
{{ instance.portainer_stack_name }}
|
||||||
|
</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="badge bg-secondary">Not set</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if instance.connection_token %}
|
{% if instance.connection_token %}
|
||||||
<span class="badge bg-success" data-bs-toggle="tooltip" title="Instance is authenticated">
|
<span class="badge bg-success" data-bs-toggle="tooltip" title="Instance is authenticated">
|
||||||
@@ -1077,12 +1088,15 @@ function compareSemanticVersions(currentVersion, latestVersion) {
|
|||||||
async function fetchVersionInfo(instanceUrl, instanceId) {
|
async function fetchVersionInfo(instanceUrl, instanceId) {
|
||||||
const row = document.querySelector(`[data-instance-id="${instanceId}"]`).closest('tr');
|
const row = document.querySelector(`[data-instance-id="${instanceId}"]`).closest('tr');
|
||||||
const versionCell = row.querySelector('td:nth-child(9)'); // Version column (adjusted after removing branch)
|
const versionCell = row.querySelector('td:nth-child(9)'); // Version column (adjusted after removing branch)
|
||||||
const paymentPlanCell = row.querySelector('td:nth-child(6)'); // Payment Plan column
|
const paymentPlanCell = document.getElementById('payment-plan-' + instanceId); // Payment Plan column - use ID selector like initial load
|
||||||
|
|
||||||
// Show loading state
|
// Show loading state
|
||||||
if (versionCell) {
|
if (versionCell) {
|
||||||
versionCell.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Loading...';
|
versionCell.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Loading...';
|
||||||
}
|
}
|
||||||
|
if (paymentPlanCell) {
|
||||||
|
paymentPlanCell.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Loading...';
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const apiKey = document.querySelector(`[data-instance-id="${instanceId}"]`).dataset.token;
|
const apiKey = document.querySelector(`[data-instance-id="${instanceId}"]`).dataset.token;
|
||||||
@@ -1116,7 +1130,10 @@ async function fetchVersionInfo(instanceUrl, instanceId) {
|
|||||||
// Update payment plan cell with pricing tier name
|
// Update payment plan cell with pricing tier name
|
||||||
if (paymentPlanCell) {
|
if (paymentPlanCell) {
|
||||||
const pricingTierName = data.pricing_tier_name || 'unknown';
|
const pricingTierName = data.pricing_tier_name || 'unknown';
|
||||||
|
console.log(`Instance ${instanceId}: API returned pricing_tier_name: "${pricingTierName}"`);
|
||||||
|
|
||||||
if (pricingTierName !== 'unknown') {
|
if (pricingTierName !== 'unknown') {
|
||||||
|
console.log(`Instance ${instanceId}: Setting payment plan to "${pricingTierName}" with badge styling`);
|
||||||
paymentPlanCell.innerHTML = `
|
paymentPlanCell.innerHTML = `
|
||||||
<span class="badge bg-info" data-bs-toggle="tooltip" title="Pricing Tier: ${pricingTierName}">
|
<span class="badge bg-info" data-bs-toggle="tooltip" title="Pricing Tier: ${pricingTierName}">
|
||||||
<i class="fas fa-tag me-1"></i>${pricingTierName}
|
<i class="fas fa-tag me-1"></i>${pricingTierName}
|
||||||
@@ -1128,8 +1145,11 @@ async function fetchVersionInfo(instanceUrl, instanceId) {
|
|||||||
new bootstrap.Tooltip(paymentPlanBadge);
|
new bootstrap.Tooltip(paymentPlanBadge);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
console.log(`Instance ${instanceId}: API returned "unknown", setting badge to unknown`);
|
||||||
paymentPlanCell.innerHTML = '<span class="badge bg-secondary">unknown</span>';
|
paymentPlanCell.innerHTML = '<span class="badge bg-secondary">unknown</span>';
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.log(`Instance ${instanceId}: paymentPlanCell not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update version cell
|
// Update version cell
|
||||||
@@ -1349,8 +1369,8 @@ async function fetchCompanyNames() {
|
|||||||
if (instanceUrl && apiKey) {
|
if (instanceUrl && apiKey) {
|
||||||
console.log(`Fetching data for instance ${instanceId}`);
|
console.log(`Fetching data for instance ${instanceId}`);
|
||||||
loadingPromises.push(
|
loadingPromises.push(
|
||||||
fetchCompanyName(instanceUrl, instanceId),
|
fetchCompanyName(instanceUrl, instanceId)
|
||||||
fetchVersionInfo(instanceUrl, instanceId) // Add version info fetching
|
// Removed fetchVersionInfo call to prevent race conditions - checkAllInstanceStatuses handles this
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const row = badge.closest('tr');
|
const row = badge.closest('tr');
|
||||||
@@ -1379,7 +1399,7 @@ async function fetchCompanyNames() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await Promise.all(loadingPromises);
|
await Promise.all(loadingPromises);
|
||||||
console.log('Finished fetching all company names, stats, and version info');
|
console.log('Finished fetching all company names and stats');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in fetchCompanyNames:', error);
|
console.error('Error in fetchCompanyNames:', error);
|
||||||
}
|
}
|
||||||
@@ -2479,5 +2499,10 @@ function validateStep6() {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Remove the payment plan fetching from here since fetchVersionInfo handles it
|
||||||
|
// The periodic refresh (every 30 seconds) will handle payment plan updates properly
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user