268 lines
14 KiB
HTML
268 lines
14 KiB
HTML
{% extends "base.html" %}
|
||
{% block title %}Medods{% endblock %}
|
||
|
||
{% block styles %}
|
||
<link rel="stylesheet" href="/static/css/medods.css">
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
<!-- Заголовок -->
|
||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||
<div>
|
||
<h2 class="mb-1"><i class="bi bi-plug me-2"></i>Medods API</h2>
|
||
<p class="text-muted mb-0">Управление подключением и запросами к Medods API</p>
|
||
</div>
|
||
<div class="badge bg-primary fs-6 px-3 py-2">
|
||
<i class="bi bi-activity me-1"></i>API Control
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Настройка подключения -->
|
||
<div class="row mb-4">
|
||
<div class="col-lg-6 mb-4 mb-lg-0">
|
||
<div class="card h-100 url-status">
|
||
<div
|
||
class="card-header bg-primary bg-opacity-10 border-primary d-flex justify-content-between align-items-center">
|
||
<h5 class="mb-0"><i class="bi bi-server me-2"></i>Настройка сервера</h5>
|
||
<span id="urlCheck" class="status-indicator">
|
||
{% if data.url %}
|
||
<span class="badge bg-success"><i class="bi bi-check-circle me-1"></i>Настроен</span>
|
||
{% else %}
|
||
<span class="badge bg-warning"><i class="bi bi-exclamation-triangle me-1"></i>Не настроен</span>
|
||
{% endif %}
|
||
</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="mb-3">
|
||
<label class="form-label fw-semibold">URL адрес сервера</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text bg-light"><i class="bi bi-link-45deg"></i></span>
|
||
<input type="text" class="form-control" id="server_url" placeholder="https://api.example.com"
|
||
value="{{ data.url or '' }}">
|
||
</div>
|
||
<div class="form-text small">Введите полный URL вашего сервера Medods API</div>
|
||
</div>
|
||
<button type="button" class="btn btn-success w-100" onclick="saveServerUrl()" id="saveServerUrlButton">
|
||
{% if data.url %}
|
||
<i class="bi bi-arrow-repeat me-2"></i>Обновить URL
|
||
{% else %}
|
||
<i class="bi bi-save me-2"></i>Сохранить URL
|
||
{% endif %}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-lg-6">
|
||
<div class="card h-100 api-status">
|
||
<div
|
||
class="card-header bg-success bg-opacity-10 border-success d-flex justify-content-between align-items-center">
|
||
<h5 class="mb-0"><i class="bi bi-key me-2"></i>API ключ</h5>
|
||
<span id="apiKeyCheck" class="status-indicator">
|
||
{% if data.apiKey %}
|
||
<span class="badge bg-success"><i class="bi bi-check-circle me-1"></i>Загружен</span>
|
||
{% else %}
|
||
<span class="badge bg-warning"><i class="bi bi-exclamation-triangle me-1"></i>Не загружен</span>
|
||
{% endif %}
|
||
</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="mb-3">
|
||
<label class="form-label fw-semibold">CSV файл с ключами</label>
|
||
<input type="file" class="form-control" id="api_key_file" accept=".csv">
|
||
<div class="form-text small">
|
||
<i class="bi bi-info-circle me-1"></i>
|
||
Файл должен содержать колонки: <code>identity;secretKey</code>
|
||
</div>
|
||
</div>
|
||
<button type="button" class="btn btn-primary w-100" onclick="uploadApiKey()" id="uploadApiKeyButton">
|
||
{% if data.apiKey %}
|
||
<i class="bi bi-arrow-repeat me-2"></i>Обновить ключ
|
||
{% else %}
|
||
<i class="bi bi-upload me-2"></i>Загрузить API ключ
|
||
{% endif %}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Основной раздел: Запросы -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-dark bg-opacity-10">
|
||
<div class="d-flex justify-content-between align-items-center">
|
||
<h4 class="mb-0"><i class="bi bi-send me-2"></i>Управление запросами</h4>
|
||
<button type="button" class="btn btn-sm btn-outline-primary" onclick="newRequest()">
|
||
<i class="bi bi-plus-circle me-1"></i>Новый запрос
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="card-body p-0">
|
||
<div class="row g-0">
|
||
<!-- Левая колонка: Список запросов -->
|
||
<div class="col-md-4 border-end">
|
||
<div class="p-3 border-bottom bg-light">
|
||
<h5 class="mb-0"><i class="bi bi-list-ul me-2"></i>Сохраненные запросы</h5>
|
||
</div>
|
||
<div class="requests-list p-3">
|
||
<div id="requestsList">
|
||
<!-- Список запросов будет загружен здесь -->
|
||
<div class="text-center py-4">
|
||
<div class="spinner-border text-primary" role="status">
|
||
<span class="visually-hidden">Загрузка...</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Правая колонка: Редактор запроса -->
|
||
<div class="col-md-8">
|
||
<div class="p-3 border-bottom bg-light">
|
||
<h5 class="mb-0">
|
||
<i class="bi bi-pencil-square me-2"></i>
|
||
<span id="editorTitle">Создание нового запроса</span>
|
||
</h5>
|
||
</div>
|
||
<div class="p-4">
|
||
<form id="requestForm">
|
||
<input type="hidden" id="requestId">
|
||
|
||
<!-- Основные поля -->
|
||
<div class="row g-3 mb-4">
|
||
<div class="col-md-6">
|
||
<label class="form-label fw-semibold">Название запроса</label>
|
||
<input type="text" class="form-control form-control-lg" id="title"
|
||
placeholder="Например: Получить список пользователей" required>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<label class="form-label fw-semibold">HTTP метод</label>
|
||
<select class="form-select form-select-lg" id="method" required>
|
||
<option value="GET">GET</option>
|
||
<option value="POST">POST</option>
|
||
<option value="PUT">PUT</option>
|
||
<option value="DELETE">DELETE</option>
|
||
<option value="PATCH">PATCH</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<label class="form-label fw-semibold">URL путь</label>
|
||
<input type="text" class="form-control form-control-lg" id="url_path"
|
||
placeholder="/users" required>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Query параметры -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-body-secondary">
|
||
<div class="d-flex justify-content-between align-items-center">
|
||
<span class="fw-semibold">
|
||
<i class="bi bi-filter me-2"></i>Query параметры
|
||
</span>
|
||
<button type="button" class="btn btn-sm btn-outline-primary"
|
||
onclick="addQueryParam()">
|
||
<i class="bi bi-plus me-1"></i>Добавить
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<div id="queryParamsContainer" class="mb-2">
|
||
<!-- Параметры будут добавляться сюда -->
|
||
</div>
|
||
<div class="text-center">
|
||
<button type="button" class="btn btn-sm btn-outline-primary"
|
||
onclick="addQueryParam()">
|
||
<i class="bi bi-plus-circle me-1"></i>Добавить параметр Query
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Payload параметры -->
|
||
<div class="card mb-4">
|
||
<div class="card-header bg-body-secondary">
|
||
<div class="d-flex justify-content-between align-items-center">
|
||
<span class="fw-semibold">
|
||
<i class="bi bi-code me-2"></i>Body параметры
|
||
</span>
|
||
<button type="button" class="btn btn-sm btn-outline-primary"
|
||
onclick="addPayloadParam()">
|
||
<i class="bi bi-plus me-1"></i>Добавить
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<div id="payloadParamsContainer" class="mb-2">
|
||
<!-- Параметры будут добавляться сюда -->
|
||
</div>
|
||
<div class="text-center">
|
||
<button type="button" class="btn btn-sm btn-outline-primary"
|
||
onclick="addPayloadParam()">
|
||
<i class="bi bi-plus-circle me-1"></i>Добавить параметр Body
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="d-flex justify-content-center align-items-center gap-2 text-muted d-none"
|
||
id="timestampDiv">
|
||
<div>
|
||
<small>Создано: </small><span class="small" id="createdAt"></span>
|
||
</div>
|
||
<div>
|
||
<small>Последнее обновление: </small><span class="small" id="updatedAt"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Кнопки действий -->
|
||
<div class="d-flex gap-3 justify-content-end pt-3 border-top">
|
||
<button type="button" class="btn btn-outline-secondary" onclick="resetForm()">
|
||
<i class="bi bi-x-lg me-1"></i>Сбросить
|
||
</button>
|
||
<button type="button" class="btn btn-primary" onclick="saveRequest()"
|
||
id="saveRequestButton">
|
||
<i class="bi bi-save me-1"></i>Сохранить запрос
|
||
</button>
|
||
<button type="button" class="btn btn-warning" onclick="executeCurrentRequest()"
|
||
id="executeButton" disabled>
|
||
<i class="bi bi-play-fill me-1"></i>Запустить
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Раздел с результатом -->
|
||
<div class="card fade-in" id="responseCard" style="display: none;">
|
||
<div class="card-header bg-info bg-opacity-10">
|
||
<div class="d-flex justify-content-between align-items-center">
|
||
<h5 class="mb-0"><i class="bi bi-arrow-return-right me-2"></i>Результат выполнения запроса</h5>
|
||
<div>
|
||
<button type="button" class="btn btn-sm btn-outline-success me-2" onclick="downloadResponse()">
|
||
<i class="bi bi-download me-1"></i>Скачать JSON
|
||
</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="toggleResponse()">
|
||
<i class="bi bi-chevron-up"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card-body" id="responseBody">
|
||
<div id="responseContainer" class="response-container">
|
||
<!-- Ответ будет отображаться здесь -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Всплывающие уведомления -->
|
||
<div id="alertContainer" style="position: fixed; top: 80px; right: 20px; z-index: 1050;"></div>
|
||
{% endblock %}
|
||
|
||
{% block scripts %}
|
||
<script>
|
||
const pageData = {{ data | tojson }};
|
||
</script>
|
||
<script src="/static/js/medods.js"></script>
|
||
{% endblock %} |