hospital-management/templates/core/integration_log_form.html
2025-08-12 13:33:25 +03:00

458 lines
23 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}{% if object %}Edit Integration Log{% else %}New Integration Log{% endif %}{% endblock %}
{% block content %}
<div class="d-flex align-items-center mb-3">
<div>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url 'core:integration_log_list' %}">Integration Logs</a></li>
<li class="breadcrumb-item active">{% if object %}Edit{% else %}New{% endif %}</li>
</ol>
<h1 class="page-header mb-0">
{% if object %}Edit Integration Log{% else %}Create Integration Log{% endif %}
</h1>
</div>
<div class="ms-auto">
<a href="{% url 'core:integration_log_list' %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Back to List
</a>
</div>
</div>
<div class="row">
<div class="col-xl-8">
<div class="card">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-exchange-alt me-2"></i>
Integration Log Details
</h4>
</div>
<div class="card-body">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
<form method="post" novalidate>
{% csrf_token %}
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.integration_name.id_for_label }}" class="form-label">Integration Name *</label>
<input type="text"
class="form-control {% if form.integration_name.errors %}is-invalid{% endif %}"
id="{{ form.integration_name.id_for_label }}"
name="{{ form.integration_name.name }}"
value="{{ form.integration_name.value|default:'' }}"
placeholder="Enter integration name"
required>
{% if form.integration_name.errors %}
<div class="invalid-feedback">
{{ form.integration_name.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.operation_type.id_for_label }}" class="form-label">Operation Type *</label>
<select class="form-select {% if form.operation_type.errors %}is-invalid{% endif %}"
id="{{ form.operation_type.id_for_label }}"
name="{{ form.operation_type.name }}"
required>
<option value="">Select Operation Type</option>
{% for choice in form.operation_type.field.choices %}
<option value="{{ choice.0 }}" {% if choice.0 == form.operation_type.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endfor %}
</select>
{% if form.operation_type.errors %}
<div class="invalid-feedback">
{{ form.operation_type.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.status.id_for_label }}" class="form-label">Status *</label>
<select class="form-select {% if form.status.errors %}is-invalid{% endif %}"
id="{{ form.status.id_for_label }}"
name="{{ form.status.name }}"
required>
{% for choice in form.status.field.choices %}
<option value="{{ choice.0 }}" {% if choice.0 == form.status.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endfor %}
</select>
{% if form.status.errors %}
<div class="invalid-feedback">
{{ form.status.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.execution_time.id_for_label }}" class="form-label">Execution Time (ms)</label>
<input type="number"
class="form-control {% if form.execution_time.errors %}is-invalid{% endif %}"
id="{{ form.execution_time.id_for_label }}"
name="{{ form.execution_time.name }}"
value="{{ form.execution_time.value|default:'' }}"
min="0"
step="1"
placeholder="Enter execution time in milliseconds">
{% if form.execution_time.errors %}
<div class="invalid-feedback">
{{ form.execution_time.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.started_at.id_for_label }}" class="form-label">Started At</label>
<input type="datetime-local"
class="form-control {% if form.started_at.errors %}is-invalid{% endif %}"
id="{{ form.started_at.id_for_label }}"
name="{{ form.started_at.name }}"
value="{{ form.started_at.value|default:'' }}">
{% if form.started_at.errors %}
<div class="invalid-feedback">
{{ form.started_at.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.completed_at.id_for_label }}" class="form-label">Completed At</label>
<input type="datetime-local"
class="form-control {% if form.completed_at.errors %}is-invalid{% endif %}"
id="{{ form.completed_at.id_for_label }}"
name="{{ form.completed_at.name }}"
value="{{ form.completed_at.value|default:'' }}">
{% if form.completed_at.errors %}
<div class="invalid-feedback">
{{ form.completed_at.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="mb-3">
<label for="{{ form.request_data.id_for_label }}" class="form-label">Request Data</label>
<textarea class="form-control {% if form.request_data.errors %}is-invalid{% endif %}"
id="{{ form.request_data.id_for_label }}"
name="{{ form.request_data.name }}"
rows="5"
placeholder="Enter request data (JSON format recommended)">{{ form.request_data.value|default:'' }}</textarea>
{% if form.request_data.errors %}
<div class="invalid-feedback">
{{ form.request_data.errors.0 }}
</div>
{% endif %}
<div class="form-text">
Enter the request payload or parameters sent to the integration endpoint.
</div>
</div>
<div class="mb-3">
<label for="{{ form.response_data.id_for_label }}" class="form-label">Response Data</label>
<textarea class="form-control {% if form.response_data.errors %}is-invalid{% endif %}"
id="{{ form.response_data.id_for_label }}"
name="{{ form.response_data.name }}"
rows="5"
placeholder="Enter response data (JSON format recommended)">{{ form.response_data.value|default:'' }}</textarea>
{% if form.response_data.errors %}
<div class="invalid-feedback">
{{ form.response_data.errors.0 }}
</div>
{% endif %}
<div class="form-text">
Enter the response received from the integration endpoint.
</div>
</div>
<div class="mb-3">
<label for="{{ form.error_message.id_for_label }}" class="form-label">Error Message</label>
<textarea class="form-control {% if form.error_message.errors %}is-invalid{% endif %}"
id="{{ form.error_message.id_for_label }}"
name="{{ form.error_message.name }}"
rows="3"
placeholder="Enter any error messages or issues encountered">{{ form.error_message.value|default:'' }}</textarea>
{% if form.error_message.errors %}
<div class="invalid-feedback">
{{ form.error_message.errors.0 }}
</div>
{% endif %}
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.retry_count.id_for_label }}" class="form-label">Retry Count</label>
<input type="number"
class="form-control {% if form.retry_count.errors %}is-invalid{% endif %}"
id="{{ form.retry_count.id_for_label }}"
name="{{ form.retry_count.name }}"
value="{{ form.retry_count.value|default:'0' }}"
min="0"
max="10">
{% if form.retry_count.errors %}
<div class="invalid-feedback">
{{ form.retry_count.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.external_id.id_for_label }}" class="form-label">External ID</label>
<input type="text"
class="form-control {% if form.external_id.errors %}is-invalid{% endif %}"
id="{{ form.external_id.id_for_label }}"
name="{{ form.external_id.name }}"
value="{{ form.external_id.value|default:'' }}"
placeholder="External system identifier">
{% if form.external_id.errors %}
<div class="invalid-feedback">
{{ form.external_id.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="mb-3">
<label for="{{ form.metadata.id_for_label }}" class="form-label">Metadata</label>
<textarea class="form-control {% if form.metadata.errors %}is-invalid{% endif %}"
id="{{ form.metadata.id_for_label }}"
name="{{ form.metadata.name }}"
rows="3"
placeholder="Additional metadata (JSON format recommended)">{{ form.metadata.value|default:'' }}</textarea>
{% if form.metadata.errors %}
<div class="invalid-feedback">
{{ form.metadata.errors.0 }}
</div>
{% endif %}
<div class="form-text">
Additional information about the integration operation.
</div>
</div>
<div class="d-flex justify-content-between">
<div>
{% if object %}
<a href="{% url 'core:integration_log_detail' object.pk %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Cancel
</a>
{% else %}
<a href="{% url 'core:integration_log_list' %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Cancel
</a>
{% endif %}
</div>
<div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-2"></i>
{% if object %}Update Log{% else %}Create Log{% endif %}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-xl-4">
<!-- Status Guide -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-info-circle me-2"></i>
Status Guide
</h5>
</div>
<div class="card-body">
<div class="mb-3">
<span class="badge bg-warning me-2">Pending</span>
<small>Operation queued for execution</small>
</div>
<div class="mb-3">
<span class="badge bg-info me-2">Running</span>
<small>Currently executing</small>
</div>
<div class="mb-3">
<span class="badge bg-success me-2">Success</span>
<small>Completed successfully</small>
</div>
<div class="mb-3">
<span class="badge bg-danger me-2">Failed</span>
<small>Execution failed</small>
</div>
<div>
<span class="badge bg-secondary me-2">Cancelled</span>
<small>Operation cancelled</small>
</div>
</div>
</div>
<!-- Operation Types -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-cogs me-2"></i>
Operation Types
</h5>
</div>
<div class="card-body">
<div class="mb-3">
<i class="fas fa-download text-primary me-2"></i>
<strong>Import</strong>
<div class="small text-muted">Data import from external system</div>
</div>
<div class="mb-3">
<i class="fas fa-upload text-success me-2"></i>
<strong>Export</strong>
<div class="small text-muted">Data export to external system</div>
</div>
<div class="mb-3">
<i class="fas fa-sync text-warning me-2"></i>
<strong>Sync</strong>
<div class="small text-muted">Bidirectional synchronization</div>
</div>
<div>
<i class="fas fa-paper-plane text-info me-2"></i>
<strong>API Call</strong>
<div class="small text-muted">External API request</div>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="card">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-bolt me-2"></i>
Quick Actions
</h5>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<button type="button" class="btn btn-outline-primary btn-sm" onclick="setCurrentTime('started_at')">
<i class="fas fa-play me-2"></i>Set Start Time
</button>
<button type="button" class="btn btn-outline-success btn-sm" onclick="setCurrentTime('completed_at')">
<i class="fas fa-check me-2"></i>Set Completion Time
</button>
<button type="button" class="btn btn-outline-info btn-sm" onclick="formatJSON('request_data')">
<i class="fas fa-code me-2"></i>Format Request JSON
</button>
<button type="button" class="btn btn-outline-info btn-sm" onclick="formatJSON('response_data')">
<i class="fas fa-code me-2"></i>Format Response JSON
</button>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const statusSelect = document.getElementById('{{ form.status.id_for_label }}');
const errorMessageField = document.getElementById('{{ form.error_message.id_for_label }}');
const startedAtField = document.getElementById('{{ form.started_at.id_for_label }}');
const completedAtField = document.getElementById('{{ form.completed_at.id_for_label }}');
// Show/hide fields based on status
function toggleFieldsBasedOnStatus() {
const status = statusSelect.value;
if (status === 'failed') {
errorMessageField.parentElement.style.display = 'block';
} else if (status === 'success') {
errorMessageField.parentElement.style.display = 'none';
errorMessageField.value = '';
}
// Auto-set timestamps based on status
if (status === 'running' && !startedAtField.value) {
setCurrentTime('started_at');
} else if ((status === 'success' || status === 'failed') && !completedAtField.value) {
setCurrentTime('completed_at');
}
}
statusSelect.addEventListener('change', toggleFieldsBasedOnStatus);
toggleFieldsBasedOnStatus(); // Initial call
// Calculate execution time automatically
function calculateExecutionTime() {
const startTime = new Date(startedAtField.value);
const endTime = new Date(completedAtField.value);
if (startTime && endTime && endTime > startTime) {
const executionTime = endTime - startTime;
document.getElementById('{{ form.execution_time.id_for_label }}').value = executionTime;
}
}
startedAtField.addEventListener('change', calculateExecutionTime);
completedAtField.addEventListener('change', calculateExecutionTime);
});
function setCurrentTime(fieldSuffix) {
const now = new Date();
const isoString = now.toISOString().slice(0, 16); // Format for datetime-local
const field = document.getElementById(`{{ form.${fieldSuffix}.id_for_label }}`.replace('${fieldSuffix}', fieldSuffix));
if (field) {
field.value = isoString;
// Trigger calculation if both times are set
if (fieldSuffix === 'completed_at') {
const startField = document.getElementById('{{ form.started_at.id_for_label }}');
if (startField.value) {
const startTime = new Date(startField.value);
const endTime = new Date(isoString);
const executionTime = endTime - startTime;
document.getElementById('{{ form.execution_time.id_for_label }}').value = executionTime;
}
}
}
}
function formatJSON(fieldName) {
const field = document.getElementById(`{{ form.${fieldName}.id_for_label }}`.replace('${fieldName}', fieldName));
if (field && field.value.trim()) {
try {
const parsed = JSON.parse(field.value);
field.value = JSON.stringify(parsed, null, 2);
} catch (e) {
alert('Invalid JSON format. Please check the syntax.');
}
}
}
</script>
{% endblock %}