238 lines
7.8 KiB
JavaScript
238 lines
7.8 KiB
JavaScript
(function() {
|
|
var TOTAL_STEPS = 5;
|
|
|
|
function tKey(key) {
|
|
return typeof t === 'function' ? t(key) : key;
|
|
}
|
|
|
|
function tfKey(key, vars) {
|
|
return typeof tf === 'function' ? tf(key, vars) : key;
|
|
}
|
|
|
|
function step3PanelId() {
|
|
return 'step-panel-3-rest';
|
|
}
|
|
|
|
function stepFile(step) {
|
|
return step === 3 ? 'step3-rest.html' : 'step' + step + '.html';
|
|
}
|
|
|
|
function panelIdForStep(step) {
|
|
return step === 3 ? step3PanelId() : 'step-panel-' + step;
|
|
}
|
|
|
|
function buildIconSvg(href, width, height) {
|
|
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
svg.setAttribute('width', String(width));
|
|
svg.setAttribute('height', String(height));
|
|
var use = document.createElementNS('http://www.w3.org/2000/svg', 'use');
|
|
use.setAttribute('href', href);
|
|
svg.appendChild(use);
|
|
return svg;
|
|
}
|
|
|
|
function appendHtmlFragment(container, html) {
|
|
if (!container) return;
|
|
var template = document.createElement('template');
|
|
template.innerHTML = html;
|
|
container.appendChild(template.content.cloneNode(true));
|
|
}
|
|
|
|
function setContinueButtonContent(button, label) {
|
|
if (!button) return;
|
|
button.textContent = label + ' ';
|
|
button.appendChild(
|
|
buildIconSvg(
|
|
(window.APP_BASE || '') + 'icons/general/arrow-right.svg#icon',
|
|
13,
|
|
13
|
|
)
|
|
);
|
|
}
|
|
|
|
function renderStepCounter(counter, step, total) {
|
|
if (!counter) return;
|
|
var language = localStorage.getItem('crank_lang') || 'en';
|
|
var parts = language === 'ru'
|
|
? { prefix: 'Шаг ', suffix: ' из ' + total }
|
|
: { prefix: 'Step ', suffix: ' of ' + total };
|
|
var strong = document.createElement('strong');
|
|
counter.textContent = parts.prefix;
|
|
strong.textContent = String(step);
|
|
counter.appendChild(strong);
|
|
counter.appendChild(document.createTextNode(parts.suffix));
|
|
}
|
|
|
|
function loadStep(step, callback) {
|
|
var panelId = step === 3 ? step3PanelId() : 'step-panel-' + step;
|
|
if (document.getElementById(panelId)) {
|
|
if (callback) callback();
|
|
return;
|
|
}
|
|
fetch(stepFile(step))
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(html) {
|
|
var container = document.getElementById('step-panel-container');
|
|
appendHtmlFragment(container, html);
|
|
var pane = document.getElementById(panelId);
|
|
var activeStep = window.currentStep || 1;
|
|
if (pane && step !== activeStep) {
|
|
pane.hidden = true;
|
|
}
|
|
if (typeof applyLang === 'function') applyLang();
|
|
if (callback) callback();
|
|
})
|
|
.catch(function() {
|
|
if (callback) callback();
|
|
});
|
|
}
|
|
|
|
function doGoToStep(step) {
|
|
document.querySelectorAll('.step-number[data-step]').forEach(function(element) {
|
|
var stepNumber = Number(element.getAttribute('data-step')) || 0;
|
|
element.textContent = tfKey('wizard.step_short', { step: stepNumber });
|
|
});
|
|
|
|
document.querySelectorAll('.step-pane').forEach(function(pane) { pane.hidden = true; });
|
|
var panelId = panelIdForStep(step);
|
|
var pane = document.getElementById(panelId);
|
|
if (pane) pane.hidden = false;
|
|
|
|
document.querySelectorAll('.step-item').forEach(function(item, index) {
|
|
var stepNumber = index + 1;
|
|
item.classList.remove('active', 'done', 'pending');
|
|
var indicator = item.querySelector('.step-indicator');
|
|
var status = item.querySelector('.step-status-text');
|
|
if (stepNumber < step) {
|
|
item.classList.add('done');
|
|
if (indicator) {
|
|
indicator.replaceChildren(
|
|
buildIconSvg(
|
|
(window.APP_BASE || '') + 'icons/general/check.svg#icon',
|
|
10,
|
|
10
|
|
)
|
|
);
|
|
}
|
|
if (status) status.textContent = tKey('wizard.status.completed');
|
|
} else if (stepNumber === step) {
|
|
item.classList.add('active');
|
|
if (indicator) indicator.textContent = stepNumber;
|
|
if (status) status.textContent = tKey('wizard.status.in_progress');
|
|
} else {
|
|
item.classList.add('pending');
|
|
if (indicator) indicator.textContent = stepNumber;
|
|
if (status) status.textContent = tKey('wizard.status.not_started');
|
|
}
|
|
});
|
|
|
|
var percent = Math.round((step / TOTAL_STEPS) * 100);
|
|
var fill = document.querySelector('.progress-bar-fill');
|
|
if (fill) fill.style.width = percent + '%';
|
|
var percentNode = document.querySelector('.progress-pct');
|
|
if (percentNode) percentNode.textContent = percent + '%';
|
|
|
|
var counter = pane ? pane.querySelector('[data-step-counter]') : null;
|
|
renderStepCounter(counter, step, TOTAL_STEPS);
|
|
|
|
var backButton = document.querySelector('.btn-back');
|
|
if (backButton) {
|
|
backButton.disabled = step === 1;
|
|
}
|
|
|
|
var continueButton = document.querySelector('.btn-continue');
|
|
if (continueButton) {
|
|
if (step === TOTAL_STEPS) {
|
|
var finalLabel = window.wizardMode === 'edit' ? tKey('wizard.button.save_changes') : tKey('wizard.button.create');
|
|
setContinueButtonContent(continueButton, finalLabel);
|
|
continueButton.classList.add('is-final-step');
|
|
} else {
|
|
setContinueButtonContent(continueButton, tKey('wizard.button.continue'));
|
|
continueButton.classList.remove('is-final-step');
|
|
}
|
|
}
|
|
|
|
window.currentStep = step;
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
}
|
|
|
|
function goToStep(step) {
|
|
if (step < 1 || step > TOTAL_STEPS) return;
|
|
loadStep(step, function() { doGoToStep(step); });
|
|
}
|
|
|
|
function loadWizardPanels(steps) {
|
|
return steps.reduce(function(chain, step) {
|
|
return chain.then(function() {
|
|
return new Promise(function(resolve) {
|
|
loadStep(step, resolve);
|
|
});
|
|
});
|
|
}, Promise.resolve());
|
|
}
|
|
|
|
window.addEventListener('crank:langchange', function() {
|
|
if (window.currentStep) {
|
|
doGoToStep(window.currentStep);
|
|
}
|
|
});
|
|
|
|
function bindProtocolCards() {
|
|
document.querySelectorAll('.protocol-card').forEach(function(card) {
|
|
card.addEventListener('click', function() {
|
|
if (card.hidden || card.getAttribute('aria-disabled') === 'true') {
|
|
return;
|
|
}
|
|
document.querySelectorAll('.protocol-card').forEach(function(item) {
|
|
item.classList.remove('selected');
|
|
item.setAttribute('aria-checked', 'false');
|
|
});
|
|
card.classList.add('selected');
|
|
card.setAttribute('aria-checked', 'true');
|
|
|
|
var protocol = card.dataset.protocol
|
|
|| 'rest';
|
|
|
|
window.wizardProtocol = protocol;
|
|
var step3Name = document.getElementById('sidebar-step-3-name');
|
|
var labels = window.CrankWizardState.step3Labels();
|
|
if (step3Name) step3Name.textContent = labels[protocol] || tKey('wizard.step3.rest.label');
|
|
|
|
});
|
|
card.addEventListener('keydown', function(event) {
|
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
event.preventDefault();
|
|
card.click();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function applyEditionProtocolVisibility(_capabilities) {
|
|
window.wizardProtocol = 'rest';
|
|
document.querySelectorAll('.protocol-card').forEach(function(card) {
|
|
var isRest = (card.dataset.protocol || 'rest') === 'rest';
|
|
card.hidden = !isRest;
|
|
card.setAttribute('aria-disabled', isRest ? 'false' : 'true');
|
|
card.classList.toggle('selected', isRest);
|
|
card.setAttribute('aria-checked', isRest ? 'true' : 'false');
|
|
});
|
|
|
|
var step3Name = document.getElementById('sidebar-step-3-name');
|
|
if (step3Name) {
|
|
step3Name.textContent = tKey('wizard.step3.rest.label');
|
|
}
|
|
}
|
|
|
|
window.CrankWizardShell = {
|
|
TOTAL_STEPS: TOTAL_STEPS,
|
|
step3PanelId: step3PanelId,
|
|
loadStep: loadStep,
|
|
doGoToStep: doGoToStep,
|
|
goToStep: goToStep,
|
|
loadWizardPanels: loadWizardPanels,
|
|
bindProtocolCards: bindProtocolCards,
|
|
applyEditionProtocolVisibility: applyEditionProtocolVisibility,
|
|
};
|
|
}());
|