connected btx (no import)
This commit is contained in:
+219
-25
@@ -11,13 +11,20 @@
|
||||
background: #f5f5f5;
|
||||
padding: 20px;
|
||||
}
|
||||
.container { max-width: 600px; margin: 0 auto; }
|
||||
.container { max-width: 800px; margin: 0 auto; }
|
||||
h1 { color: #333; margin-bottom: 20px; }
|
||||
.card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
padding: 24px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.card h2 {
|
||||
color: #333;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 2px solid #eee;
|
||||
}
|
||||
.form-group { margin-bottom: 20px; }
|
||||
label {
|
||||
@@ -56,11 +63,11 @@
|
||||
font-weight: 500;
|
||||
}
|
||||
.btn:hover { background: #0056b3; }
|
||||
.btn-secondary {
|
||||
background: #6c757d;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.btn-secondary { background: #6c757d; margin-left: 10px; }
|
||||
.btn-secondary:hover { background: #545b62; }
|
||||
.btn-test { background: #28a745; margin-left: 10px; }
|
||||
.btn-test:hover { background: #218838; }
|
||||
.btn-test:disabled { background: #ccc; cursor: not-allowed; }
|
||||
.error {
|
||||
background: #ffebee;
|
||||
color: #c62828;
|
||||
@@ -90,6 +97,52 @@
|
||||
font-size: 13px;
|
||||
color: #e65100;
|
||||
}
|
||||
.test-result {
|
||||
margin-top: 12px;
|
||||
padding: 12px;
|
||||
border-radius: 6px;
|
||||
display: none;
|
||||
}
|
||||
.test-result.success {
|
||||
background: #e8f5e9;
|
||||
color: #388e3c;
|
||||
display: block;
|
||||
}
|
||||
.test-result.error {
|
||||
background: #ffebee;
|
||||
color: #c62828;
|
||||
display: block;
|
||||
}
|
||||
.webhook-instructions {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 6px;
|
||||
padding: 16px;
|
||||
margin-top: 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.webhook-instructions ol {
|
||||
margin-left: 20px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.webhook-instructions li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.webhook-instructions code {
|
||||
background: #e9ecef;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-family: monospace;
|
||||
}
|
||||
.saved-indicator {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
padding: 4px 8px;
|
||||
background: #e8f5e9;
|
||||
color: #388e3c;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -98,16 +151,28 @@
|
||||
|
||||
<h1>⚙️ Настройки подключения</h1>
|
||||
|
||||
{% if error.is_some() %}
|
||||
<div class="error">{{ error.as_ref().unwrap() }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% if success.is_some() %}
|
||||
<div class="success">{{ success.as_ref().unwrap() }}</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Redmine Settings -->
|
||||
<div class="card">
|
||||
{% if error.is_some() %}
|
||||
<div class="error">{{ error.as_ref().unwrap() }}</div>
|
||||
{% endif %}
|
||||
<h2>
|
||||
🔴 Redmine
|
||||
{% if !redmine_url.is_empty() %}
|
||||
<span class="saved-indicator">✓ Сохранено</span>
|
||||
{% endif %}
|
||||
</h2>
|
||||
|
||||
{% if success.is_some() %}
|
||||
<div class="success">{{ success.as_ref().unwrap() }}</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="POST" action="/settings">
|
||||
<form method="POST" action="/settings" id="redmine-form">
|
||||
<!-- Скрытые поля для сохранения Bitrix настроек -->
|
||||
<input type="hidden" name="bitrix_url" value="{{ bitrix_url }}">
|
||||
<input type="hidden" name="bitrix_webhook" value="{{ bitrix_webhook }}">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="redmine_url">Redmine URL</label>
|
||||
<input
|
||||
@@ -115,10 +180,9 @@
|
||||
id="redmine_url"
|
||||
name="redmine_url"
|
||||
value="{{ redmine_url }}"
|
||||
placeholder="https://redmine.example.com"
|
||||
required
|
||||
placeholder="https://redmine.company.com"
|
||||
>
|
||||
<div class="help-text">Полный URL вашего Redmine, например: https://redmine.company.com</div>
|
||||
<div class="help-text">Полный URL вашего Redmine</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@@ -128,10 +192,12 @@
|
||||
id="redmine_api_key"
|
||||
name="redmine_api_key"
|
||||
value=""
|
||||
placeholder="Ваш API ключ из настроек Redmine"
|
||||
required
|
||||
placeholder="Введите API ключ для сохранения"
|
||||
>
|
||||
<div class="help-text">Ключ можно получить в Настройки → Мой аккаунт → API access key</div>
|
||||
{% if !redmine_url.is_empty() %}
|
||||
<div class="help-text" style="color: #388e3c;">✓ API ключ уже сохранён в сессии</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@@ -142,20 +208,148 @@
|
||||
name="redmine_user_id"
|
||||
value="{{ redmine_user_id }}"
|
||||
placeholder="7"
|
||||
required
|
||||
>
|
||||
<div class="help-text">Ваш ID пользователя в Redmine (видно в профиле или URL)</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn">💾 Сохранить настройки</button>
|
||||
<a href="/" class="btn btn-secondary">Отмена</a>
|
||||
<button type="submit" class="btn">💾 Сохранить Redmine</button>
|
||||
<button type="button" class="btn btn-test" onclick="testRedmineConnection()">🔍 Тест подключения</button>
|
||||
<div id="redmine-test-result" class="test-result"></div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Bitrix24 Settings -->
|
||||
<div class="card">
|
||||
<h2>
|
||||
🔵 Bitrix24
|
||||
{% if !bitrix_url.is_empty() %}
|
||||
<span class="saved-indicator">✓ Сохранено</span>
|
||||
{% endif %}
|
||||
</h2>
|
||||
|
||||
<div class="security-note">
|
||||
🔒 <strong>Безопасность:</strong> Ваши учётные данные хранятся только в сессии браузера и не сохраняются на сервере.
|
||||
При закрытии браузера сессия истекает и данные удаляются.
|
||||
</div>
|
||||
<form method="POST" action="/settings" id="bitrix-form">
|
||||
<!-- Скрытые поля для сохранения Redmine настроек -->
|
||||
<input type="hidden" name="redmine_url" value="{{ redmine_url }}">
|
||||
<input type="hidden" name="redmine_user_id" value="{{ redmine_user_id }}">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="bitrix_url">Bitrix24 URL</label>
|
||||
<input
|
||||
type="text"
|
||||
id="bitrix_url"
|
||||
name="bitrix_url"
|
||||
value="{{ bitrix_url }}"
|
||||
placeholder="https://corp.company.com"
|
||||
>
|
||||
<div class="help-text">URL вашего портала Bitrix24</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="bitrix_webhook">Входящий вебхук</label>
|
||||
<input
|
||||
type="text"
|
||||
id="bitrix_webhook"
|
||||
name="bitrix_webhook"
|
||||
value="{{ bitrix_webhook }}"
|
||||
placeholder="rest/105/abc123xyz/"
|
||||
>
|
||||
<div class="help-text">Код вебхука из раздела Разработчикам</div>
|
||||
{% if !bitrix_url.is_empty() %}
|
||||
<div class="help-text" style="color: #388e3c;">✓ Вебхук уже сохранён в сессии</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="webhook-instructions">
|
||||
<strong>📋 Как получить входящий вебхук в Bitrix24:</strong>
|
||||
<ol>
|
||||
<li>Откройте ваш Bitrix24 портал</li>
|
||||
<li>Перейдите в меню <code>Разработчикам</code> (внизу левого меню)</li>
|
||||
<li>Выберите <code>Другое</code> → <code>Входящий вебхук</code></li>
|
||||
<li>Выберите права доступа: <code>tasks</code>, <code>user</code>, <code>department</code></li>
|
||||
<li>Нажмите <code>Создать вебхук</code></li>
|
||||
<li>Скопируйте URL вида <code>https://your-portal.com/rest/105/CODE/</code></li>
|
||||
<li>В поле выше вставьте только часть после домена: <code>rest/105/CODE/</code></li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn">💾 Сохранить Bitrix24</button>
|
||||
<button type="button" class="btn btn-test" onclick="testBitrixConnection()">🔍 Тест подключения</button>
|
||||
<div id="bitrix-test-result" class="test-result"></div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="security-note">
|
||||
🔒 <strong>Безопасность:</strong> Ваши учётные данные хранятся только в сессии браузера и не сохраняются на сервере.
|
||||
При закрытии браузера сессия истекает и данные удаляются.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function testRedmineConnection() {
|
||||
const resultDiv = document.getElementById('redmine-test-result');
|
||||
const btn = event.target;
|
||||
|
||||
btn.disabled = true;
|
||||
btn.textContent = '⏳ Проверка...';
|
||||
resultDiv.className = 'test-result';
|
||||
resultDiv.textContent = '';
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/test/redmine', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
resultDiv.className = 'test-result success';
|
||||
resultDiv.textContent = '✅ ' + data.message;
|
||||
} else {
|
||||
resultDiv.className = 'test-result error';
|
||||
resultDiv.textContent = '❌ ' + data.message;
|
||||
}
|
||||
} catch (e) {
|
||||
resultDiv.className = 'test-result error';
|
||||
resultDiv.textContent = '❌ Ошибка: ' + e.message;
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btn.textContent = '🔍 Тест подключения';
|
||||
}
|
||||
}
|
||||
|
||||
async function testBitrixConnection() {
|
||||
const resultDiv = document.getElementById('bitrix-test-result');
|
||||
const btn = event.target;
|
||||
|
||||
btn.disabled = true;
|
||||
btn.textContent = '⏳ Проверка...';
|
||||
resultDiv.className = 'test-result';
|
||||
resultDiv.textContent = '';
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/test/bitrix', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
resultDiv.className = 'test-result success';
|
||||
resultDiv.textContent = '✅ ' + data.message;
|
||||
} else {
|
||||
resultDiv.className = 'test-result error';
|
||||
resultDiv.textContent = '❌ ' + data.message;
|
||||
}
|
||||
} catch (e) {
|
||||
resultDiv.className = 'test-result error';
|
||||
resultDiv.textContent = '❌ Ошибка: ' + e.message;
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btn.textContent = '🔍 Тест подключения';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user