You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

172 lines
7.4 KiB

  1. {# templates/timetracking/week.html.twig #}
  2. {% extends 'base.html.twig' %}
  3. {#
  4. Datums-Arrays kommen aus AppExtension (single source of truth).
  5. Skalare Strings kommen aus messages.de.yaml via |trans.
  6. #}
  7. {% set months = deMonths() %}
  8. {% set monthsShort = deMonthsShort() %}
  9. {% set weekdays = deWeekdays() %}
  10. {% set weekdaysShort= deWeekdaysShort() %}
  11. {% block title %}
  12. {% set monthName = months[currentDate|date('n') - 1] %}
  13. {% set activStr = currentDate|date('Y-m-d') %}
  14. {% if activStr == todayStr %}
  15. {{ 'app.date.today'|trans }}, {{ currentDate|date('j') }}. {{ monthName }}
  16. {% elseif activStr == tomorrowStr %}
  17. {{ 'app.date.tomorrow'|trans }}, {{ currentDate|date('j') }}. {{ monthName }}
  18. {% elseif activStr == yesterdayStr %}
  19. {{ 'app.date.yesterday'|trans }}, {{ currentDate|date('j') }}. {{ monthName }}
  20. {% else %}
  21. {{ weekdays[currentDate|date('N') - 1] }}, {{ currentDate|date('j') }}. {{ monthName }}
  22. {% endif %}
  23. {% endblock %}
  24. {% block body %}
  25. <script>
  26. window.TT = {
  27. activeDate: '{{ currentDate|date('Y-m-d') }}',
  28. trackingInterval: {{ trackingInterval }},
  29. projects: [
  30. {% for project in projects %}
  31. { id: {{ project.id }}, name: {{ project.name|json_encode|raw }}, clientName: {{ project.client.name|json_encode|raw }} }{% if not loop.last %},{% endif %}
  32. {% endfor %}
  33. ],
  34. services: [
  35. {% for service in services %}
  36. { id: {{ service.id }}, name: {{ service.name|json_encode|raw }}, billable: {{ service.billable ? 'true' : 'false' }} }{% if not loop.last %},{% endif %}
  37. {% endfor %}
  38. ],
  39. i18n: {
  40. today: {{ 'app.date.today'|trans|json_encode|raw }},
  41. tomorrow: {{ 'app.date.tomorrow'|trans|json_encode|raw }},
  42. yesterday: {{ 'app.date.yesterday'|trans|json_encode|raw }},
  43. weekLabel: {{ 'app.date.week_label'|trans|json_encode|raw }},
  44. months: {{ months|json_encode|raw }},
  45. monthsShort: {{ monthsShort|json_encode|raw }},
  46. weekdays: {{ weekdays|json_encode|raw }},
  47. weekdaysShort: {{ weekdaysShort|json_encode|raw }},
  48. prevWeek: {{ 'app.nav.prev_week'|trans|json_encode|raw }},
  49. nextWeek: {{ 'app.nav.next_week'|trans|json_encode|raw }},
  50. monthView: {{ 'app.nav.month_view'|trans|json_encode|raw }},
  51. prevMonth: {{ 'app.nav.prev_month'|trans|json_encode|raw }},
  52. nextMonth: {{ 'app.nav.next_month'|trans|json_encode|raw }},
  53. billable: {{ 'app.service.billable'|trans|json_encode|raw }},
  54. notBillable: {{ 'app.service.not_billable'|trans|json_encode|raw }},
  55. selectPh: {{ 'app.entry.select_placeholder'|trans|json_encode|raw }},
  56. noEntries: {{ 'app.entry.no_entries'|trans|json_encode|raw }},
  57. btnSave: {{ 'app.entry.btn_save'|trans|json_encode|raw }},
  58. btnCancel: {{ 'app.entry.btn_cancel'|trans|json_encode|raw }},
  59. btnEdit: {{ 'app.entry.btn_edit'|trans|json_encode|raw }},
  60. btnDelete: {{ 'app.entry.btn_delete'|trans|json_encode|raw }},
  61. labelDuration: {{ 'app.entry.label_duration'|trans|json_encode|raw }},
  62. labelProjectService: {{ 'app.entry.label_project_service'|trans|json_encode|raw }},
  63. labelNote: {{ 'app.entry.label_note'|trans|json_encode|raw }},
  64. confirmDelete: {{ 'app.entry.confirm_delete'|trans|json_encode|raw }},
  65. errorNoProject: {{ 'app.entry.error_no_project'|trans|json_encode|raw }},
  66. errorSave: {{ 'app.entry.error_save'|trans|json_encode|raw }},
  67. errorDelete: {{ 'app.entry.error_delete'|trans|json_encode|raw }},
  68. errorLoad: {{ 'app.entry.error_load'|trans|json_encode|raw }},
  69. durationHint: {{ 'app.entry.duration_hint'|trans|json_encode|raw }},
  70. errorZeroDuration: {{ 'app.entry.error_zero_duration'|trans|json_encode|raw }},
  71. errorDurationTooLong: {{ 'app.entry.error_duration_too_long'|trans|json_encode|raw }},
  72. warnDurationLong: {{ 'app.entry.warn_duration_long'|trans|json_encode|raw }},
  73. invoicedTitle: {{ 'app.entry.invoiced_title'|trans|json_encode|raw }},
  74. },
  75. };
  76. </script>
  77. <div class="tt-page">
  78. {% include '_sections/tt-header.html.twig' %}
  79. <div class="greeting">
  80. <span class="greeting__text">{{ greeting }}, {{ firstName }}!</span>
  81. </div>
  82. <main class="tt-content">
  83. <div class="entry-form" id="entry-form">
  84. <div class="entry-form__grid">
  85. <label class="entry-form__label">{{ 'app.entry.label_duration'|trans }}</label>
  86. <div class="entry-form__field">
  87. <input type="text" id="create-duration" class="input input--sm" value="0:00" autocomplete="off" />
  88. {% include '_atoms/duration-help.html.twig' %}
  89. </div>
  90. <label class="entry-form__label">{{ 'app.entry.label_project_service'|trans }}</label>
  91. <div class="entry-form__field entry-form__field--selects">
  92. <select id="create-project" class="select">
  93. <option value="">{{ 'app.entry.select_placeholder'|trans }}</option>
  94. {% set currentClient = null %}
  95. {% for project in projects %}
  96. {% if project.client.name != currentClient %}
  97. {% if currentClient is not null %}</optgroup>{% endif %}
  98. <optgroup label="{{ project.client.name }}">
  99. {% set currentClient = project.client.name %}
  100. {% endif %}
  101. <option value="{{ project.id }}">{{ project.name }}</option>
  102. {% endfor %}
  103. {% if currentClient is not null %}</optgroup>{% endif %}
  104. </select>
  105. <select id="create-service" class="select">
  106. <option value="">{{ 'app.entry.select_placeholder'|trans }}</option>
  107. {% set currentGroup = null %}
  108. {% for service in services %}
  109. {% set group = service.billable ? 'app.service.billable'|trans : 'app.service.not_billable'|trans %}
  110. {% if group != currentGroup %}
  111. {% if currentGroup is not null %}</optgroup>{% endif %}
  112. <optgroup label="{{ group }}">
  113. {% set currentGroup = group %}
  114. {% endif %}
  115. <option value="{{ service.id }}">{{ service.name }}</option>
  116. {% endfor %}
  117. {% if currentGroup is not null %}</optgroup>{% endif %}
  118. </select>
  119. </div>
  120. <label class="entry-form__label">{{ 'app.entry.label_note'|trans }}</label>
  121. <div class="entry-form__field">
  122. <textarea id="create-note" class="textarea" rows="3"
  123. placeholder="{{ 'app.entry.placeholder_note'|trans }}"></textarea>
  124. </div>
  125. <div class="entry-form__actions">
  126. <button type="button" class="btn btn-primary" id="btn-create">
  127. {{ 'app.entry.btn_create'|trans }}
  128. </button>
  129. </div>
  130. </div>
  131. </div>
  132. <div class="entry-list" id="entry-list" data-date="{{ currentDate|date('Y-m-d') }}">
  133. {% if timeEntries is empty %}
  134. <div class="empty-state" id="empty-state">
  135. <p class="empty-state__title">{{ 'app.entry.no_entries'|trans }}</p>
  136. </div>
  137. {% else %}
  138. <div class="entry-list__items" id="entry-items">
  139. {% for entry in timeEntries %}
  140. {% include 'timetracking/_entry_row.html.twig' with { entry: entry } %}
  141. {% endfor %}
  142. </div>
  143. <div class="entry-list__footer" id="entry-footer">
  144. <span class="entry-list__total">{{ totalDuration }}</span>
  145. </div>
  146. {% endif %}
  147. </div>
  148. </main>
  149. </div>
  150. {% endblock %}
  151. {% block javascripts %}
  152. {{ parent() }}
  153. {% endblock %}