Edit and create timesheet records in modal (#603)
- added loading indicator for datatables - fix multiple reloads of datatable content
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% import "macros/widgets.html.twig" as widgets %}
|
||||
{% import "macros/datatables.html.twig" as tables %}
|
||||
{% extends app.request.xmlHttpRequest ? 'form.html.twig' : 'base.html.twig' %}
|
||||
|
||||
{% block page_title %}{{ 'admin_activity.title'|trans }}{% endblock %}
|
||||
{% block page_subtitle %}{{ 'admin_activity.subtitle'|trans }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ include('default/_form.html.twig', {
|
||||
{{ include(app.request.xmlHttpRequest ? 'default/_form_modal.html.twig' : 'default/_form.html.twig', {
|
||||
'title': activity.name|default('create'|trans),
|
||||
'form': form,
|
||||
'back': path('admin_activity')
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% import "macros/widgets.html.twig" as widgets %}
|
||||
{% import "macros/datatables.html.twig" as tables %}
|
||||
{% extends app.request.xmlHttpRequest ? 'form.html.twig' : 'base.html.twig' %}
|
||||
|
||||
{% block page_title %}{{ 'admin_customer.title'|trans }}{% endblock %}
|
||||
{% block page_subtitle %}{{ 'admin_customer.subtitle'|trans }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ include('default/_form.html.twig', {
|
||||
{{ include(app.request.xmlHttpRequest ? 'default/_form_modal.html.twig' : 'default/_form.html.twig', {
|
||||
'title': customer.name|default('create'|trans),
|
||||
'form': form,
|
||||
'back': path('admin_customer')
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% import "macros/widgets.html.twig" as widgets %}
|
||||
{% import "macros/datatables.html.twig" as tables %}
|
||||
{% extends app.request.xmlHttpRequest ? 'form.html.twig' : 'base.html.twig' %}
|
||||
|
||||
{% block page_title %}{{ 'admin_project.title'|trans }}{% endblock %}
|
||||
{% block page_subtitle %}{{ 'admin_project.subtitle'|trans }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ include('default/_form.html.twig', {
|
||||
{{ include(app.request.xmlHttpRequest ? 'default/_form_modal.html.twig' : 'default/_form.html.twig', {
|
||||
'title': project.name|default('create'|trans),
|
||||
'form': form,
|
||||
'back': path('admin_project')
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
{% endif %}
|
||||
{% set actions = actions|merge({'visibility': '#modal_timesheet_admin'}) %}
|
||||
{% if is_granted('create_other_timesheet') %}
|
||||
{% set actions = actions|merge({'create': path('admin_timesheet_create')}) %}
|
||||
{% set actions = actions|merge({'create': {'url': path('admin_timesheet_create'), 'class': 'modal-ajax-form'}}) %}
|
||||
{% endif %}
|
||||
{{ widgets.page_actions(actions) }}
|
||||
{% endblock %}
|
||||
@@ -87,7 +87,7 @@
|
||||
<td>
|
||||
{% set actionButtons = {} %}
|
||||
{% if is_granted('edit', entry) %}
|
||||
{% set actionButtons = {'edit': path('admin_timesheet_edit', {'id' : entry.id, 'page': page})}|merge(actionButtons) %}
|
||||
{% set actionButtons = actionButtons|merge({'edit': {'url': path('admin_timesheet_edit', {'id': entry.id, 'page': page}), 'class': 'modal-ajax-form'}}) %}
|
||||
{% endif %}
|
||||
{% if not entry.end and is_granted('stop', entry) %}
|
||||
{% set actionButtons = {'stop': path('admin_timesheet_stop', {'id' : entry.id})}|merge(actionButtons) %}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% import "macros/widgets.html.twig" as widgets %}
|
||||
{% import "macros/datatables.html.twig" as tables %}
|
||||
{% extends app.request.xmlHttpRequest ? 'form.html.twig' : 'base.html.twig' %}
|
||||
|
||||
{% block page_title %}{{ 'timesheet.title'|trans }}{% endblock %}
|
||||
{% block page_subtitle %}{{ 'timesheet.subtitle'|trans }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ include('default/_form.html.twig', {
|
||||
{{ include(app.request.xmlHttpRequest ? 'default/_form_modal.html.twig' : 'default/_form.html.twig', {
|
||||
'title': (entry.id ? 'timesheet.edit'|trans : 'create'|trans),
|
||||
'form': form,
|
||||
'back': path('admin_timesheet')
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
<div class="toolbar-pad no-print">
|
||||
{% block main_before %}{% endblock %}
|
||||
</div>
|
||||
{% embed 'embeds/modal.html.twig' %}
|
||||
{% block modal_id %}remote_form_modal{% endblock %}
|
||||
{% block modal_title %}{% endblock %}
|
||||
{% block modal_body %}{% endblock %}
|
||||
{% block modal_footer %}{% endblock %}
|
||||
{% endembed %}
|
||||
{% endblock %}
|
||||
|
||||
{% block avanzu_page_content_after %}
|
||||
@@ -100,7 +106,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
{# we do not call parent() as we use a custom built for the frontend assets and don't want the default <script> #}
|
||||
{# no call to parent(), as we use a custom built for the frontend assets and don't want the default <script> #}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$.kimai.init({
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% import "macros/widgets.html.twig" as widgets %}
|
||||
{% import "macros/datatables.html.twig" as tables %}
|
||||
{% import "macros/toolbar.html.twig" as toolbar %}
|
||||
|
||||
{% block page_title %}{{ 'calendar.title'|trans }}{% endblock %}
|
||||
{% block page_subtitle %}{{ 'calendar.subtitle'|trans }}{% endblock %}
|
||||
{% block page_actions %}{{ widgets.page_actions({'list': path('timesheet'), 'create': path('timesheet_create', {'origin': 'calendar'})}) }}{% endblock %}
|
||||
|
||||
{% block page_actions %}
|
||||
{% set actions = {'list': path('timesheet')} %}
|
||||
{% if is_granted('create_own_timesheet') %}
|
||||
{% set actions = actions|merge({'create': {'url': path('timesheet_create', {'origin': 'calendar'})}}) %}
|
||||
{% endif %}
|
||||
{{ widgets.page_actions(actions) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<div class="row">
|
||||
|
||||
18
templates/default/_form_modal.html.twig
Normal file
18
templates/default/_form_modal.html.twig
Normal file
@@ -0,0 +1,18 @@
|
||||
{% embed 'embeds/modal.html.twig' %}
|
||||
{% block modal_id %}form_modal{% endblock %}
|
||||
{% block modal_before %}{{ form_start(form) }}{% endblock %}
|
||||
{% block modal_title %}
|
||||
{{ title }}
|
||||
{% if form.vars.docu_chapter is defined and form.vars.docu_chapter is not empty %}
|
||||
<a href="{{ path('help_chapter', {'chapter': form.vars.docu_chapter}) }}"><i class="{{ 'help'|icon }}"></i></a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block modal_body %}
|
||||
{{ form_widget(form) }}
|
||||
{% endblock %}
|
||||
{% block modal_footer %}
|
||||
<button type="button" class="btn btn-default btn-cancel" data-dismiss="modal">{{ 'action.close'|trans }}</button>
|
||||
<button type="submit" class="btn btn-primary modal-form-save" data-loading-text="Loading..." id="{{ block('modal_id') }}_save">{{ 'action.save'|trans }}</button>
|
||||
{% endblock %}
|
||||
{% block modal_end %}{{ form_end(form) }}{% endblock %}
|
||||
{% endembed %}
|
||||
18
templates/embeds/modal.html.twig
Normal file
18
templates/embeds/modal.html.twig
Normal file
@@ -0,0 +1,18 @@
|
||||
<div class="modal fade" id="{{ block('modal_id') }}" tabindex="-1" role="dialog" aria-labelledby="{{ block('modal_id') }}_label">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
{% if block('modal_before') is defined %}{{ block('modal_before') }}{% endif %}
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="{{ 'action.close'|trans }}"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="{{ block('modal_id') }}_label">{{ block('modal_title') }}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{{ block('modal_body') }}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{{ block('modal_footer') }}
|
||||
</div>
|
||||
{% if block('modal_end') is defined %}{{ block('modal_end') }}{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -8,7 +8,7 @@
|
||||
{% block page_actions %}
|
||||
{% set actions = {
|
||||
'filter': '#collapseExport',
|
||||
'fas fa-toggle-off': {'id':'export-toggle-button'}
|
||||
'off': {'id':'export-toggle-button'}
|
||||
} %}
|
||||
{{ widgets.page_actions(actions) }}
|
||||
{% endblock %}
|
||||
@@ -26,24 +26,6 @@
|
||||
{% if entries is empty %}
|
||||
{{ widgets.callout('warning', 'error.no_entries_found') }}
|
||||
{% else %}
|
||||
{#
|
||||
{% set columns = {'date': ''} %}
|
||||
|
||||
{% if not duration_only %}
|
||||
{% set columns = columns|merge({'starttime': 'hidden-xs', 'endtime': 'hidden-xs'}) %}
|
||||
{% endif %}
|
||||
|
||||
{% set columns = columns|merge({
|
||||
'duration': '',
|
||||
'rate': '',
|
||||
'customer': 'hidden-xs hidden-sm',
|
||||
'project': 'hidden-xs hidden-sm',
|
||||
'activity': 'hidden-xs hidden-sm',
|
||||
'username': 'hidden-xs',
|
||||
'description': 'hidden-xs hidden-sm',
|
||||
'actions': 'alwaysVisible',
|
||||
}) %}
|
||||
#}
|
||||
{% set columns = {
|
||||
'date': '',
|
||||
'user': 'hidden-xs hidden-sm',
|
||||
|
||||
11
templates/form.html.twig
Normal file
11
templates/form.html.twig
Normal file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ app.request.locale }}">
|
||||
<head></head>
|
||||
<body class="ajax-forms">
|
||||
<div id="ajax-messages">
|
||||
{{ include('@AdminLTE/Partials/_flash_messages.html.twig') }}
|
||||
</div>
|
||||
<div id="ajax-form">
|
||||
{{ block('main') }}
|
||||
</div>
|
||||
</body>
|
||||
@@ -59,7 +59,7 @@
|
||||
{% set rate = entry.user.preferenceValue('hourly_rate') %}
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td>{{ entry.begin|date_short }}</td>
|
||||
<td class="text-nowrap">{{ entry.begin|date_short }}</td>
|
||||
<td class="hidden-xs hidden-sm">{{ widgets.label_user(entry.user) }}</td>
|
||||
<td class="hidden-xs hidden-sm timesheet-description">
|
||||
{% if entry.description is not empty %}
|
||||
@@ -69,8 +69,8 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">{{ rate|money(model.calculator.currency) }}</td>
|
||||
<td class="text-center">{{ duration }}</td>
|
||||
<td class="text-right">{{ entry.rate|money(model.calculator.currency) }}</td>
|
||||
<td class="text-center text-nowrap">{{ duration }}</td>
|
||||
<td class="text-right text-nowrap">{{ entry.rate|money(model.calculator.currency) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{{ tables.data_table_footer(entries) }}
|
||||
|
||||
@@ -3,54 +3,10 @@
|
||||
{% endmacro %}
|
||||
|
||||
{%- macro page_actions(tools) -%}
|
||||
{% import _self as macro %}
|
||||
<div class="breadcrumb">
|
||||
<div class="box-tools">
|
||||
<div class="btn-group">
|
||||
{%- for icon,values in tools %}
|
||||
{% spaceless %}
|
||||
{% set id = null %}
|
||||
{% set onclick = null %}
|
||||
{% set modal = null %}
|
||||
{% set toggle = null %}
|
||||
{% set url = null %}
|
||||
|
||||
{% if not values is iterable %}
|
||||
{% set url = values %}
|
||||
{% if 'onclick:' in url %}
|
||||
{% set onclick = url|replace({'onclick:': ''}) %}
|
||||
{% set url = '#' %}
|
||||
{% endif %}
|
||||
{% if '#collapse' in url %}
|
||||
{% set toggle = 'collapse' %}
|
||||
{% endif %}
|
||||
{% if '#modal' in url %}
|
||||
{% set modal = url %}
|
||||
{% set url = '#' %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% set url = values.url ?? '#' %}
|
||||
{% set onclick = values.onclick ?? null %}
|
||||
{% set modal = values.modal ?? null %}
|
||||
{% set toggle = values.toggle ?? null %}
|
||||
{% set id = values.id ?? null %}
|
||||
{% endif %}
|
||||
{% endspaceless %}
|
||||
<a class="btn btn-default" href="{{ url }}"
|
||||
{%- if id is not empty -%}
|
||||
id="{{ id }}"
|
||||
{%- endif -%}
|
||||
{%- if toggle is not empty -%}
|
||||
data-toggle="{{ toggle }}"
|
||||
{%- endif -%}
|
||||
{%- if modal is not empty -%}
|
||||
data-toggle="modal" data-target="{{ modal }}"
|
||||
{%- endif -%}
|
||||
{%- if onclick is not empty -%}
|
||||
onclick="{{ onclick }}"
|
||||
{%- endif -%}
|
||||
><i class="{{ icon|icon(icon) }}"></i></a>
|
||||
{% endfor -%}
|
||||
</div>
|
||||
{{ macro.button_group(tools) }}
|
||||
</div>
|
||||
</div>
|
||||
{%- endmacro -%}
|
||||
@@ -190,14 +146,57 @@
|
||||
{% macro button_group(actions) %}
|
||||
{% import _self as macro %}
|
||||
<div class="btn-group">
|
||||
{% for icon, url in actions %}
|
||||
{{ macro.button_action(icon, url) }}
|
||||
{% endfor %}
|
||||
{%- for icon,values in actions %}
|
||||
{% spaceless %}
|
||||
{% set id = null %}
|
||||
{% set onclick = null %}
|
||||
{% set modal = null %}
|
||||
{% set toggle = null %}
|
||||
{% set url = null %}
|
||||
{% set class = "btn btn-default btn-" ~ icon ~ " " %}
|
||||
|
||||
{% if not values is iterable %}
|
||||
{% set url = values %}
|
||||
{% if 'onclick:' in url %}
|
||||
{% set onclick = url|replace({'onclick:': ''}) %}
|
||||
{% set url = '#' %}
|
||||
{% endif %}
|
||||
{% if '#collapse' in url %}
|
||||
{% set toggle = 'collapse' %}
|
||||
{% endif %}
|
||||
{% if '#modal' in url %}
|
||||
{% set modal = url %}
|
||||
{% set url = '#' %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% set url = values.url ?? '#' %}
|
||||
{% set onclick = values.onclick ?? null %}
|
||||
{% set modal = values.modal ?? null %}
|
||||
{% set toggle = values.toggle ?? null %}
|
||||
{% set id = values.id ?? null %}
|
||||
{% set class = class ~ ( values.class | default("")) %}
|
||||
{% endif %}
|
||||
{% endspaceless %}
|
||||
<a class="{{ class | trim }}" href="{{ url }}"
|
||||
{%- if id is not empty -%}
|
||||
id="{{ id }}"
|
||||
{%- endif -%}
|
||||
{%- if toggle is not empty -%}
|
||||
data-toggle="{{ toggle }}"
|
||||
{%- endif -%}
|
||||
{%- if modal is not empty -%}
|
||||
data-toggle="modal" data-target="{{ modal }}"
|
||||
{%- endif -%}
|
||||
{%- if onclick is not empty -%}
|
||||
onclick="{{ onclick }}"
|
||||
{%- endif -%}
|
||||
>{{ macro.icon(icon) }}</a>
|
||||
{% endfor -%}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro button_action(icon, url) %}
|
||||
<a href="{{ url }}" class="btn btn-default btn-{{ icon }}">
|
||||
<i class="{{ icon|icon(icon) }}"></i>
|
||||
{{ macro.icon(icon) }}
|
||||
</a>
|
||||
{% endmacro %}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% import "macros/widgets.html.twig" as widgets %}
|
||||
{% import "macros/datatables.html.twig" as tables %}
|
||||
{% extends app.request.xmlHttpRequest ? 'form.html.twig' : 'base.html.twig' %}
|
||||
|
||||
{% block page_title %}{{ 'timesheet.title'|trans }}{% endblock %}
|
||||
{% block page_subtitle %}{{ 'timesheet.subtitle'|trans }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ include('default/_form.html.twig', {
|
||||
{{ include(app.request.xmlHttpRequest ? 'default/_form_modal.html.twig' : 'default/_form.html.twig', {
|
||||
'title': (entry.id ? 'timesheet.edit'|trans : 'create'|trans),
|
||||
'form': form,
|
||||
'back': path('timesheet')
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
{% block page_actions %}
|
||||
{% set actions = {'filter': '#collapseTimesheet'} %}
|
||||
{% if is_granted('export_own_timesheet') %}
|
||||
{% set actions = actions|merge({'download': 'onclick:return exportTimesheet()'}) %}
|
||||
{% set actions = actions|merge({'download': {'onclick': 'return exportTimesheet()'}}) %}
|
||||
{% endif %}
|
||||
{% set actions = actions|merge({'visibility': '#modal_timesheet'}) %}
|
||||
{% set actions = actions|merge({'calendar': path('calendar')}) %}
|
||||
{% if is_granted('create_own_timesheet') %}
|
||||
{% set actions = actions|merge({'create': path('timesheet_create')}) %}
|
||||
{% set actions = actions|merge({'create': {'url': path('timesheet_create'), 'class': 'modal-ajax-form'}}) %}
|
||||
{% endif %}
|
||||
{{ widgets.page_actions(actions) }}
|
||||
{% endblock %}
|
||||
@@ -119,7 +119,7 @@
|
||||
<td>
|
||||
{% set actionButtons = {} %}
|
||||
{% if is_granted('edit', entry) %}
|
||||
{% set actionButtons = actionButtons|merge({'edit': path('timesheet_edit', {'id' : entry.id, 'page': page})}) %}
|
||||
{% set actionButtons = actionButtons|merge({'edit': {'url': path('timesheet_edit', {'id': entry.id, 'page': page}), 'class': 'modal-ajax-form'}}) %}
|
||||
{% endif %}
|
||||
|
||||
{% if entry.end %}
|
||||
|
||||
Reference in New Issue
Block a user