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.
 
 
 
 
 

185 lines
8.7 KiB

  1. {# templates/service/index.html.twig #}
  2. {% extends 'base.html.twig' %}
  3. {% block title %}{{ 'app.service.page_title'|trans }}{% endblock %}
  4. {% block body %}
  5. <script>
  6. window.CRUD = {
  7. apiBase: '/api/services',
  8. i18n: {
  9. confirmDelete: {{ 'app.crud.confirm_delete'|trans|json_encode|raw }},
  10. confirmArchive: {{ 'app.crud.confirm_archive'|trans|json_encode|raw }},
  11. errorSave: {{ 'app.crud.error_save'|trans|json_encode|raw }},
  12. errorDelete: {{ 'app.crud.error_delete'|trans|json_encode|raw }},
  13. errorArchive: {{ 'app.crud.error_archive'|trans|json_encode|raw }},
  14. errorRestore: {{ 'app.crud.error_restore'|trans|json_encode|raw }},
  15. errorNoName: {{ 'app.crud.error_no_name'|trans|json_encode|raw }},
  16. selectPh: {{ 'app.crud.select_ph'|trans|json_encode|raw }},
  17. labelName: {{ 'app.crud.label_name'|trans|json_encode|raw }},
  18. labelRate: {{ 'app.crud.label_rate'|trans|json_encode|raw }},
  19. labelNote: {{ 'app.crud.label_note'|trans|json_encode|raw }},
  20. labelClient: {{ 'app.crud.label_client'|trans|json_encode|raw }},
  21. labelBillable: {{ 'app.service.label_billable'|trans|json_encode|raw }},
  22. billableLabel: {{ 'app.service.billable_checkbox'|trans|json_encode|raw }},
  23. btnSave: {{ 'app.entry.btn_save'|trans|json_encode|raw }},
  24. btnCancel: {{ 'app.entry.btn_cancel'|trans|json_encode|raw }},
  25. btnEdit: {{ 'app.entry.btn_edit'|trans|json_encode|raw }},
  26. btnDelete: {{ 'app.entry.btn_delete'|trans|json_encode|raw }},
  27. btnRestore: {{ 'app.crud.btn_restore'|trans|json_encode|raw }},
  28. groupBillable: {{ 'app.service.billable'|trans|json_encode|raw }},
  29. groupNotBillable: {{ 'app.service.not_billable'|trans|json_encode|raw }},
  30. projectSingular: {{ 'app.crud.project_singular'|trans|json_encode|raw }},
  31. projectPlural: {{ 'app.crud.project_plural'|trans|json_encode|raw }},
  32. rateModeDefault: {{ 'app.crud.rate_mode_default'|trans|json_encode|raw }},
  33. rateModeCustom: {{ 'app.crud.rate_mode_custom'|trans|json_encode|raw }},
  34. },
  35. };
  36. </script>
  37. <div class="crud-page">
  38. <div class="crud-page__header">
  39. <h1 class="crud-page__title">{{ 'app.service.page_title'|trans }}</h1>
  40. <button class="btn btn-primary" id="btn-new">{{ 'app.service.btn_new'|trans }}</button>
  41. </div>
  42. <div class="crud-create" id="crud-create">
  43. <div class="entry-form__grid">
  44. <label class="entry-form__label">{{ 'app.crud.label_name'|trans }}</label>
  45. <div class="entry-form__field">
  46. <input type="text" id="create-name" class="input" placeholder="{{ 'app.service.placeholder_name'|trans }}" />
  47. </div>
  48. <label class="entry-form__label">{{ 'app.service.label_billable'|trans }}</label>
  49. <div class="entry-form__field">
  50. <label class="crud-checkbox-label">
  51. <input type="checkbox" id="create-billable" checked />
  52. <span>{{ 'app.service.billable_checkbox'|trans }}</span>
  53. </label>
  54. </div>
  55. <label class="entry-form__label">{{ 'app.crud.label_rate'|trans }}</label>
  56. <div class="entry-form__field entry-form__field--rate">
  57. <input type="number" id="create-rate" class="input input--rate" placeholder="0,00" step="0.01" min="0" />
  58. <span class="entry-form__unit">&euro;</span>
  59. </div>
  60. <label class="entry-form__label">{{ 'app.crud.label_note'|trans }}</label>
  61. <div class="entry-form__field">
  62. <textarea id="create-note" class="textarea" rows="2"></textarea>
  63. </div>
  64. <div class="entry-form__actions">
  65. <button type="button" class="btn btn-primary" id="btn-create-save">{{ 'app.entry.btn_create'|trans }}</button>
  66. <button type="button" class="btn btn-secondary" id="btn-create-cancel">{{ 'app.entry.btn_cancel'|trans }}</button>
  67. </div>
  68. </div>
  69. </div>
  70. <div class="crud-tabs">
  71. <button class="crud-tab crud-tab--active" data-tab="active">{{ 'app.crud.tab_active'|trans }}</button>
  72. <button class="crud-tab" data-tab="archived">{{ 'app.crud.tab_archived'|trans }}</button>
  73. </div>
  74. <div class="crud-list" id="crud-list">
  75. {% set currentGroup = null %}
  76. {% for service in services %}
  77. {% set group = service.billable ? 'app.service.billable'|trans : 'app.service.not_billable'|trans %}
  78. {% if group != currentGroup %}
  79. {% if currentGroup is not null %}</div>{% endif %}
  80. <div class="crud-list__group">
  81. <div class="crud-list__group-label">{{ group }}</div>
  82. {% set currentGroup = group %}
  83. {% endif %}
  84. <div class="crud-row{% if service.isArchived() %} crud-row--archived{% endif %}"
  85. id="service-{{ service.id }}"
  86. data-id="{{ service.id }}"
  87. data-archived="{{ service.isArchived() ? '1' : '0' }}"
  88. data-name="{{ service.name|e('html_attr') }}"
  89. data-billable="{{ service.billable ? '1' : '0' }}"
  90. data-rate="{{ service.hourlyRate|default('') }}"
  91. data-note="{{ service.note|default('')|e('html_attr') }}">
  92. <div class="crud-row__display">
  93. <div class="crud-row__info">
  94. <span class="crud-row__name">{{ service.name }}</span>
  95. </div>
  96. <div class="crud-row__actions">
  97. {% if service.isArchived() %}
  98. <button class="crud-row__btn crud-row__btn--restore" data-action="unarchive" title="{{ 'app.crud.btn_restore'|trans }}">
  99. <svg viewBox="0 0 16 16" fill="none"><path d="M2 8a6 6 0 1 1 1.5 3.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><path d="M2 13V9h4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
  100. </button>
  101. {% else %}
  102. <button class="crud-row__btn crud-row__btn--edit" data-action="edit" title="{{ 'app.entry.btn_edit'|trans }}">
  103. <svg viewBox="0 0 16 16" fill="none"><path d="M11 2l3 3L5 14H2v-3L11 2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
  104. </button>
  105. <button class="crud-row__btn crud-row__btn--delete" data-action="delete" title="{{ 'app.entry.btn_delete'|trans }}">
  106. <svg viewBox="0 0 16 16" fill="none"><path d="M3 4h10M6 4V2h4v2M5 4l.5 9h5l.5-9" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
  107. </button>
  108. {% endif %}
  109. </div>
  110. </div>
  111. {% if not service.isArchived() %}
  112. <div class="crud-row__edit" hidden>
  113. <div class="entry-form__grid entry-form__grid--inline">
  114. <label class="entry-form__label">{{ 'app.crud.label_name'|trans }}</label>
  115. <div class="entry-form__field">
  116. <input type="text" class="input edit-name" value="{{ service.name }}" />
  117. </div>
  118. <label class="entry-form__label">{{ 'app.service.label_billable'|trans }}</label>
  119. <div class="entry-form__field">
  120. <label class="crud-checkbox-label">
  121. <input type="checkbox" class="edit-billable" {{ service.billable ? 'checked' : '' }} />
  122. <span>{{ 'app.service.billable_checkbox'|trans }}</span>
  123. </label>
  124. </div>
  125. <label class="entry-form__label">{{ 'app.crud.label_rate'|trans }}</label>
  126. <div class="entry-form__field entry-form__field--rate">
  127. <input type="number" class="input input--rate edit-rate"
  128. value="{{ service.hourlyRate|default('') }}" step="0.01" min="0" />
  129. <span class="entry-form__unit">&euro;</span>
  130. </div>
  131. <label class="entry-form__label">{{ 'app.crud.label_note'|trans }}</label>
  132. <div class="entry-form__field">
  133. <textarea class="textarea edit-note" rows="2">{{ service.note|default('') }}</textarea>
  134. </div>
  135. <div class="entry-form__actions">
  136. <button type="button" class="btn btn-primary" data-action="save">{{ 'app.entry.btn_save'|trans }}</button>
  137. <button type="button" class="btn btn-secondary" data-action="cancel">{{ 'app.entry.btn_cancel'|trans }}</button>
  138. </div>
  139. </div>
  140. </div>
  141. {% endif %}
  142. </div>
  143. {% else %}
  144. <div class="empty-state">
  145. <p class="empty-state__title">{{ 'app.service.empty'|trans }}</p>
  146. </div>
  147. {% endfor %}
  148. {% if currentGroup is not null %}</div>{% endif %}
  149. </div>
  150. </div>
  151. {% endblock %}
  152. {% block javascripts %}
  153. {{ parent() }}
  154. {{ encore_entry_script_tags('crud') }}
  155. {% endblock %}