Programming

6. pagesss


{% block extra_js %}

<script>

document.addEventListener('DOMContentLoaded', function () {

  const form  = document.getElementById('drp-form');

  const go    = document.getElementById('drp-go');

  const force = document.getElementById('drp-force');

  const panel = document.getElementById('drp-panel');

  const step  = document.getElementById('drp-step');

  const bar   = document.getElementById('drp-bar');

  const pf    = document.getElementById('pf');

  const pt    = document.getElementById('pt');

  const sp    = document.getElementById('sp');

  if (!form) return;

 

  // every <option value> on the period selects, oldest first

  const all = Array.from(pf.options).map(o => o.value).filter(Boolean);

 

  function csrf() {

    const i = form.querySelector('[name=csrfmiddlewaretoken]');

    if (i) return i.value;

    const m = document.cookie.match(/csrftoken=([^;]+)/);

    return m ? m[1] : '';

  }

 

  function show(text, cls) {

    panel.classList.add('on');

    panel.classList.remove('err', 'ok');

    if (cls) panel.classList.add(cls);

    bar.style.display = cls ? 'none' : 'block';

    step.innerHTML = text;

  }

 

  // Presets just set the three selects; the form is still the source of truth.

  document.querySelectorAll('.preset').forEach(b => {

    b.addEventListener('click', () => {

      const n = parseInt(b.dataset.months, 10);

      if (!all.length) return;

      pf.value = n > 0 ? (all[Math.max(0, all.length - n)] || '') : '';

      pt.value = '';

      sp.value = '';

    });

  });

 

  // The run can take minutes, so the page polls instead of waiting on the POST.

  async function poll(id) {

    try {

      const r = await fetch(`status/${id}/`);

      const s = await r.json();

 

      if (s.status === 'done') {

        const st = s.stats || {};

        show(`Готово за ${s.seconds} с — ${st.n_charts || '—'} графиков, ` +

             `${st.n_periods || 0} отчётных дат, ` +

             `${(st.n_clients || 0).toLocaleString('ru-RU')} клиентов. ` +

             `<a class="go-link" href="view/${id}/" target="_blank" rel="noopener">` +

             `Открыть отчёт</a>`, 'ok');

        window.open(`view/${id}/`, '_blank', 'noopener');

        go.disabled = false;

        setTimeout(() => window.location.reload(), 2000);

        return;

      }

      if (s.status === 'failed') {

        show('Ошибка: ' + (s.error || '').split('\n')[0], 'err');

        go.disabled = false;

        return;

      }

      show((s.step || 'выполняется') + ` … ${s.seconds} с`);

      setTimeout(() => poll(id), 1200);

    } catch (e) {

      show('Потеряна связь с сервером: ' + e.message, 'err');

      go.disabled = false;

    }

  }

 

  form.addEventListener('submit', async (ev) => {

    ev.preventDefault();

    go.disabled = true;

    show('Проверка готовых отчётов…');

    try {

      const r = await fetch('start/', {

        method: 'POST',

        headers: {'X-CSRFToken': csrf()},

        body: new FormData(form),

      });

      const s = await r.json();

      if (!r.ok) {

        show('Ошибка: ' + (s.error || r.status), 'err');

        go.disabled = false;

        force.value = '0';

        return;

      }

      if (s.cached) show('Такой отчёт уже построен — открываю…');

      else show('Запуск расчёта…');

      force.value = '0';

      poll(s.id);

    } catch (e) {

      show('Не удалось запустить: ' + e.message, 'err');

      go.disabled = false;

      force.value = '0';

    }

  });

});

</script>

{% endblock %}

Foydali bo'ldimi? Yoqmadi 0 Baholash uchun kiring