1
0

import_upload.twig 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. {% extends "layout.twig" %}
  2. {% set errorMessages = {
  3. 'no_file': 'No file was uploaded.',
  4. 'too_big': 'The file is larger than 5 MB.',
  5. 'partial': 'The upload was interrupted. Try again.',
  6. 'upload_invalid': 'Upload validation failed.',
  7. 'not_xlsx': 'That doesn’t look like an .xlsx file.',
  8. 'parse_failed': 'Could not parse the workbook. Open it in Excel to confirm it’s not corrupted.',
  9. 'too_large_payload': 'The parsed workbook is too large for a preview session (limit: 2 MB). Split sheets or shorten task lists and try again.',
  10. 'expired': 'Your previous import session expired. Please upload again.',
  11. 'nothing_selected': 'No sheets were selected to import.',
  12. 'server': 'Server upload error.',
  13. 'size': 'File size is invalid.',
  14. 'unknown': 'Upload failed.',
  15. } %}
  16. {% block content %}
  17. <section class="max-w-2xl">
  18. <h1 class="text-2xl font-semibold tracking-tight">Import sprints from XLSX</h1>
  19. <p class="text-slate-600 mt-1 text-sm dark:text-slate-400">
  20. Upload the team’s <em>Tool_Sprint Planning</em> workbook. Each tab is parsed
  21. as one sprint; the next step lets you confirm targets, names, dates,
  22. and review the diff before committing.
  23. </p>
  24. {% if error != '' and errorMessages[error] is defined %}
  25. <div class="mt-4 rounded-md border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-800 dark:bg-red-900 dark:border-red-800 dark:text-red-200">
  26. {{ errorMessages[error] }}
  27. </div>
  28. {% endif %}
  29. <form method="post" action="/sprints/import" enctype="multipart/form-data"
  30. class="mt-6 space-y-4 rounded-lg border bg-white p-5 dark:bg-slate-800 dark:border-slate-700">
  31. <input type="hidden" name="_csrf" value="{{ csrfToken }}">
  32. <label class="block">
  33. <span class="text-sm text-slate-700 dark:text-slate-300">Workbook (.xlsx, max 5 MB)</span>
  34. <input type="file" name="xlsx" accept=".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" required
  35. class="mt-1 block w-full text-sm text-slate-700 file:mr-3 file:rounded-md file:border-0 file:bg-slate-900 file:text-white file:px-3 file:py-2 dark:text-slate-200 dark:file:bg-slate-700">
  36. </label>
  37. <details class="text-sm text-slate-600 dark:text-slate-400">
  38. <summary class="cursor-pointer select-none">How are cell colours mapped to status?</summary>
  39. <ul class="mt-2 ml-5 list-disc space-y-1">
  40. <li>Greens (e.g. Excel “Green”, light pastel green) → <strong>abgeschlossen</strong>.</li>
  41. <li>Yellows and oranges → <strong>gestartet</strong>.</li>
  42. <li>Reds → <strong>abgebrochen</strong>.</li>
  43. <li>White, blue, or no fill → <strong>zugewiesen</strong> (default).</li>
  44. </ul>
  45. <p class="mt-2">Workers and tasks are matched to existing rows by name (case-insensitive).
  46. Anything not yet in the database is created.</p>
  47. </details>
  48. <div class="flex gap-3 pt-2">
  49. <button type="submit"
  50. class="rounded-md bg-slate-900 text-white px-4 py-2 text-sm font-medium hover:bg-slate-800 dark:bg-slate-700 dark:hover:bg-slate-600">
  51. Upload &amp; preview
  52. </button>
  53. <a href="/" class="inline-flex items-center rounded-md border border-slate-300 bg-white text-slate-700 px-4 py-2 text-sm hover:bg-slate-100 dark:bg-slate-800 dark:border-slate-600 dark:text-slate-200 dark:hover:bg-slate-700">
  54. Cancel
  55. </a>
  56. </div>
  57. </form>
  58. </section>
  59. {% endblock %}