25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

187 lines
8.3 KiB

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