chore: save current changes
This commit is contained in:
@@ -1988,7 +1988,7 @@ async function exportCSV() {
|
||||
const resp = await fetch('/api/export/csv', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({items: exportItems, name: configName, project_uuid: projectUUID, article: article})
|
||||
body: JSON.stringify({items: exportItems, name: configName, project_uuid: projectUUID, article: article, server_count: serverCount, pricelist_id: selectedPricelistIds.estimate || null})
|
||||
});
|
||||
|
||||
const blob = await resp.blob();
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="action-buttons" class="mt-4 grid grid-cols-1 sm:grid-cols-5 gap-3">
|
||||
<div id="action-buttons" class="mt-4 grid grid-cols-1 sm:grid-cols-6 gap-3">
|
||||
<button onclick="openNewVariantModal()" class="py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 font-medium">
|
||||
+ Новый вариант
|
||||
</button>
|
||||
@@ -43,6 +43,9 @@
|
||||
<button onclick="openProjectSettingsModal()" class="py-2 bg-gray-700 text-white rounded-lg hover:bg-gray-800 font-medium">
|
||||
Параметры
|
||||
</button>
|
||||
<button onclick="exportProject()" class="py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 font-medium">
|
||||
Экспорт CSV
|
||||
</button>
|
||||
<button id="delete-variant-btn" onclick="deleteVariant()" class="py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 font-medium hidden">
|
||||
Удалить вариант
|
||||
</button>
|
||||
@@ -383,8 +386,12 @@ function renderConfigs(configs) {
|
||||
}
|
||||
html += '<td class="px-4 py-3 text-sm text-gray-500">' + escapeHtml(author) + '</td>';
|
||||
html += '<td class="px-4 py-3 text-sm text-gray-500">$' + unitPrice.toLocaleString('en-US', {minimumFractionDigits: 2}) + '</td>';
|
||||
html += '<td class="px-4 py-3 text-sm text-gray-500">' + serverCount + '</td>';
|
||||
html += '<td class="px-4 py-3 text-sm text-right">$' + total.toLocaleString('en-US', {minimumFractionDigits: 2}) + '</td>';
|
||||
if (configStatusMode === 'archived') {
|
||||
html += '<td class="px-4 py-3 text-sm text-gray-500">' + serverCount + '</td>';
|
||||
} else {
|
||||
html += '<td class="px-4 py-3 text-sm text-gray-500"><input type="number" min="1" value="' + serverCount + '" class="w-16 px-1 py-0.5 border rounded text-center text-sm" data-uuid="' + c.uuid + '" data-prev="' + serverCount + '" onchange="updateConfigServerCount(this)"></td>';
|
||||
}
|
||||
html += '<td class="px-4 py-3 text-sm text-right" data-total-uuid="' + c.uuid + '">$' + total.toLocaleString('en-US', {minimumFractionDigits: 2}) + '</td>';
|
||||
const versionNo = c.current_version_no || 1;
|
||||
html += '<td class="px-4 py-3 text-sm text-center text-gray-500">v' + versionNo + '</td>';
|
||||
html += '<td class="px-4 py-3 text-sm text-right space-x-2">';
|
||||
@@ -411,7 +418,7 @@ function renderConfigs(configs) {
|
||||
html += '<tr>';
|
||||
html += '<td class="px-4 py-3 text-sm font-medium text-gray-700" colspan="4">Итого по проекту</td>';
|
||||
html += '<td class="px-4 py-3 text-sm text-gray-700">' + configs.length + '</td>';
|
||||
html += '<td class="px-4 py-3 text-sm text-right font-semibold text-gray-900">$' + totalSum.toLocaleString('en-US', {minimumFractionDigits: 2}) + '</td>';
|
||||
html += '<td class="px-4 py-3 text-sm text-right font-semibold text-gray-900" data-footer-total="1">$' + totalSum.toLocaleString('en-US', {minimumFractionDigits: 2}) + '</td>';
|
||||
html += '<td class="px-4 py-3"></td>';
|
||||
html += '<td class="px-4 py-3"></td>';
|
||||
html += '</tr>';
|
||||
@@ -874,6 +881,60 @@ document.addEventListener('keydown', function(e) {
|
||||
}
|
||||
});
|
||||
|
||||
async function updateConfigServerCount(input) {
|
||||
const uuid = input.dataset.uuid;
|
||||
const prevValue = parseInt(input.dataset.prev) || 1;
|
||||
const newValue = parseInt(input.value);
|
||||
if (!newValue || newValue < 1) {
|
||||
input.value = prevValue;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const resp = await fetch('/api/configs/' + uuid + '/server-count', {
|
||||
method: 'PATCH',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({server_count: newValue})
|
||||
});
|
||||
if (!resp.ok) {
|
||||
input.value = prevValue;
|
||||
showToast('Не удалось обновить количество', 'error');
|
||||
return;
|
||||
}
|
||||
const updated = await resp.json();
|
||||
input.dataset.prev = newValue;
|
||||
// Update row total price
|
||||
const totalCell = document.querySelector('[data-total-uuid="' + uuid + '"]');
|
||||
if (totalCell && updated.total_price != null) {
|
||||
totalCell.textContent = '$' + updated.total_price.toLocaleString('en-US', {minimumFractionDigits: 2});
|
||||
}
|
||||
// Update the config in allConfigs and recalculate footer total
|
||||
for (let i = 0; i < allConfigs.length; i++) {
|
||||
if (allConfigs[i].uuid === uuid) {
|
||||
allConfigs[i].total_price = updated.total_price;
|
||||
allConfigs[i].server_count = newValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateFooterTotal();
|
||||
} catch (e) {
|
||||
input.value = prevValue;
|
||||
showToast('Ошибка сети', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
function updateFooterTotal() {
|
||||
let totalSum = 0;
|
||||
allConfigs.forEach(c => { totalSum += (c.total_price || 0); });
|
||||
const footer = document.querySelector('tfoot td[data-footer-total]');
|
||||
if (footer) {
|
||||
footer.textContent = '$' + totalSum.toLocaleString('en-US', {minimumFractionDigits: 2});
|
||||
}
|
||||
}
|
||||
|
||||
function exportProject() {
|
||||
window.location.href = '/api/projects/' + projectUUID + '/export';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async function() {
|
||||
applyStatusModeUI();
|
||||
const ok = await loadProject();
|
||||
|
||||
Reference in New Issue
Block a user