x-control-panel/api-sandbox/app/main.js

266 lines
9.0 KiB
JavaScript

import $ from 'jquery'
let apiSpec = null
let currentUser = null
async function loadUserProfile() {
try {
const requestData = {
jsonrpc: '2.0',
method: 'Profile.get',
params: {},
id: Date.now()
}
const response = await fetch('http://localhost:8080/api', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include',
body: JSON.stringify(requestData)
})
const result = await response.json()
if (result.result) {
currentUser = result.result
$('#username').text(currentUser.name || 'неизвестный пользователь')
} else {
currentUser = null
$('#username').text('не авторизован')
}
} catch (error) {
console.error('Ошибка загрузки профиля:', error)
currentUser = null
$('#username').text('не авторизован')
}
}
async function loadApiSpec() {
try {
const response = await fetch('/api.spec.json', {
method: 'GET',
headers: {
'Cache-Control': 'no-cache',
'Accept': 'application/json'
}
})
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
}
const data = await response.json()
apiSpec = data.modules
console.log('API Spec loaded:', data)
return apiSpec
} catch (error) {
console.error('Ошибка загрузки API спецификации:', error)
$('#result').text('Ошибка загрузки API спецификации: ' + error.message)
}
}
function populateServices() {
const $serviceSelect = $('#service')
$serviceSelect.empty()
$serviceSelect.append('<option value="">Выберите сервис</option>')
apiSpec.forEach(service => {
$serviceSelect.append(`<option value="${service.name}">${service.name}</option>`)
})
}
function populateMethods(serviceName) {
const $methodSelect = $('#method')
$methodSelect.empty()
$methodSelect.append('<option value="">Выберите метод</option>')
if (serviceName) {
const service = apiSpec.find(s => s.name === serviceName)
if (service && service.methods) {
service.methods.forEach(method => {
$methodSelect.append(`<option value="${method.name}">${method.name}</option>`)
})
}
}
}
function createParamInputs(methodName, serviceName) {
const $paramsContainer = $('#params-container')
$paramsContainer.empty()
if (!serviceName || !methodName) return
const service = apiSpec.find(s => s.name === serviceName)
if (!service || !service.methods) return
const method = service.methods.find(m => m.name === methodName)
if (!method || !method.params) return
method.params.forEach(param => {
const required = !param.optional ? ' (обязательно)' : ' (необязательно)'
const isOptional = param.optional
const isObjectOrArray = param.type === 'object' || param.type === 'array'
const defaultValue = param.type === 'object' ? '{}' : (param.type === 'array' ? '[]' : '')
const inputElement = isObjectOrArray
? `<textarea id="param-${param.name}" data-param="${param.name}" placeholder="${param.description}" rows="4" style="font-family: 'Courier New', monospace;">${defaultValue}</textarea>`
: `<input type="text" id="param-${param.name}" data-param="${param.name}" placeholder="${param.description}">`
if (isOptional) {
const $paramDiv = $(`
<div class="param">
<div class="param-header">
<label for="param-${param.name}">${param.name}${required} (${param.type}):</label>
<div class="checkbox-wrapper">
<input type="checkbox" id="defined-${param.name}" data-param="${param.name}" class="defined-checkbox">
<label for="defined-${param.name}">is defined</label>
</div>
</div>
${inputElement}
</div>
`)
$paramsContainer.append($paramDiv)
$(`#defined-${param.name}`).on('change', function () {
const $input = $(`#param-${param.name}`)
const isChecked = $(this).is(':checked')
$input.prop('disabled', !isChecked)
if (!isChecked) {
$input.val(isObjectOrArray ? defaultValue : '')
}
})
// Initially disable optional fields
$(`#param-${param.name}`).prop('disabled', true)
} else {
const $paramDiv = $(`
<div class="param">
<label for="param-${param.name}">${param.name}${required} (${param.type}):</label>
${inputElement}
</div>
`)
$paramsContainer.append($paramDiv)
}
})
}
async function sendRequest() {
const serviceName = $('#service').val()
const methodName = $('#method').val()
if (!serviceName || !methodName) {
$('#result').text('Выберите сервис и метод')
return
}
const params = {}
let parseError = null
$('.param').each(function () {
const $checkbox = $(this).find('.defined-checkbox')
const $input = $(this).find('input[type="text"], textarea')
const paramName = $input.data('param')
const paramType = $input.attr('id').replace('param-', '')
// Find parameter type from method definition
const service = apiSpec.find(s => s.name === serviceName)
const method = service.methods.find(m => m.name === methodName)
const paramDef = method.params.find(p => p.name === paramName)
const isObjectOrArray = paramDef && (paramDef.type === 'object' || paramDef.type === 'array')
if ($checkbox.length > 0) {
// Optional parameter
if ($checkbox.is(':checked') && $input.val().trim() !== '') {
const value = $input.val().trim()
if (isObjectOrArray) {
try {
params[paramName] = JSON.parse(value)
} catch (e) {
parseError = `Ошибка парсинга JSON для поля "${paramName}": ${e.message}`
}
} else {
params[paramName] = value
}
}
} else {
// Required parameter
const value = $input.val().trim()
if (value !== '') {
if (isObjectOrArray) {
try {
params[paramName] = JSON.parse(value)
} catch (e) {
parseError = `Ошибка парсинга JSON для поля "${paramName}": ${e.message}`
}
} else {
params[paramName] = value
}
}
}
})
if (parseError) {
$('#result').text(parseError)
$('#request').text(JSON.stringify(requestData, null, 2))
return
}
const requestData = {
jsonrpc: '2.0',
method: `${serviceName}.${methodName}`,
params: params,
id: Date.now()
}
$('#result').text('Отправка запроса...')
$('#request').text('')
try {
const response = await fetch('http://localhost:8080/api', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include',
body: JSON.stringify(requestData)
})
const result = await response.json()
$('#result').text(JSON.stringify(result, null, 2))
$('#request').text(JSON.stringify(requestData, null, 2))
// Проверяем, нужно ли обновить профиль пользователя
if (result.result && (
methodName.startsWith('authenticateBy') ||
methodName === 'logout'
)) {
await loadUserProfile()
}
} catch (error) {
$('#result').text(`Ошибка: ${error.message}`)
$('#request').text(JSON.stringify(requestData, null, 2))
}
}
$(document).ready(async () => {
apiSpec = await loadApiSpec()
if (apiSpec) {
populateServices()
// Автоматически загружаем профиль пользователя
await loadUserProfile()
$('#service').on('change', function () {
const serviceName = $(this).val()
populateMethods(serviceName)
$('#params-container').empty()
})
$('#method').on('change', function () {
const serviceName = $('#service').val()
const methodName = $(this).val()
createParamInputs(methodName, serviceName)
})
$('#send-btn').on('click', sendRequest)
}
})