show daily sum in calendar week and day view (#2519)
This commit is contained in:
@@ -86,7 +86,7 @@ export default class KimaiActiveRecords extends KimaiPlugin {
|
|||||||
`<h4>` +
|
`<h4>` +
|
||||||
`<span>${ timesheet.activity.name }</span>` +
|
`<span>${ timesheet.activity.name }</span>` +
|
||||||
`<small>` +
|
`<small>` +
|
||||||
`<span data-title="true" data-since="${ timesheet.begin }" data-format="${ this.attributes['format'] }">${ durations.formatDuration(timesheet.duration, this.attributes['format']) }</span>` +
|
`<span data-title="true" data-since="${ timesheet.begin }">${ durations.formatDuration(timesheet.duration) }</span>` +
|
||||||
`</small>` +
|
`</small>` +
|
||||||
`</h4>` +
|
`</h4>` +
|
||||||
`<p>${ timesheet.project.name } (${ timesheet.project.customer.name })</p>` +
|
`<p>${ timesheet.project.name } (${ timesheet.project.customer.name })</p>` +
|
||||||
|
|||||||
@@ -50,8 +50,7 @@ export default class KimaiActiveRecordsDuration extends KimaiPlugin {
|
|||||||
|
|
||||||
for(let record of activeRecords) {
|
for(let record of activeRecords) {
|
||||||
const since = record.getAttribute('data-since');
|
const since = record.getAttribute('data-since');
|
||||||
const format = record.getAttribute('data-format');
|
const duration = this.formatDuration(since);
|
||||||
const duration = this.formatDuration(since, format);
|
|
||||||
if (record.getAttribute('data-title') !== null && duration !== '?') {
|
if (record.getAttribute('data-title') !== null && duration !== '?') {
|
||||||
durations.push(duration);
|
durations.push(duration);
|
||||||
}
|
}
|
||||||
@@ -75,22 +74,7 @@ export default class KimaiActiveRecordsDuration extends KimaiPlugin {
|
|||||||
document.title = title;
|
document.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
formatDuration(since, format) {
|
formatDuration(since) {
|
||||||
const duration = moment.duration(moment(new Date()).diff(moment(since)));
|
return this.getPlugin('date').formatDuration(since);
|
||||||
|
|
||||||
let hours = parseInt(duration.asHours()).toString();
|
|
||||||
let minutes = duration.minutes();
|
|
||||||
let seconds = duration.seconds();
|
|
||||||
|
|
||||||
if (hours < 0 || minutes < 0 || seconds < 0) {
|
|
||||||
return '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
// special case for hours, as they can overflow the 24h barrier - Kimai does not support days as duration unit
|
|
||||||
if (hours.length === 1) {
|
|
||||||
hours = '0' + hours;
|
|
||||||
}
|
|
||||||
|
|
||||||
return format.replace('%h', hours).replace('%m', ('0'+minutes).substr(-2)).replace('%s', ('0'+seconds).substr(-2));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,4 +26,39 @@ export default class KimaiDateUtils extends KimaiPlugin {
|
|||||||
return moment.localeData().months();
|
return moment.localeData().months();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
formatDuration(since) {
|
||||||
|
const duration = moment.duration(moment(new Date()).diff(moment(since)));
|
||||||
|
|
||||||
|
return this.formatMomentDuration(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
formatSeconds(seconds) {
|
||||||
|
const duration = moment.duration('PT' + seconds + 'S');
|
||||||
|
|
||||||
|
return this.formatMomentDuration(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
formatMomentDuration(duration) {
|
||||||
|
const hours = parseInt(duration.asHours()).toString();
|
||||||
|
const minutes = duration.minutes();
|
||||||
|
const seconds = duration.seconds();
|
||||||
|
|
||||||
|
return this.formatTime(hours, minutes, seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
formatTime(hours, minutes, seconds) {
|
||||||
|
if (hours < 0 || minutes < 0 || seconds < 0) {
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
|
||||||
|
// special case for hours, as they can overflow the 24h barrier - Kimai does not support days as duration unit
|
||||||
|
if (hours.length === 1) {
|
||||||
|
hours = '0' + hours;
|
||||||
|
}
|
||||||
|
|
||||||
|
const format = this.getConfiguration('formatDuration');
|
||||||
|
|
||||||
|
return format.replace('%h', hours).replace('%m', ('0'+minutes).substr(-2)).replace('%s', ('0'+seconds).substr(-2));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
|||||||
"build/runtime.098eaae1.js",
|
"build/runtime.098eaae1.js",
|
||||||
"build/0.9ec1fb96.js",
|
"build/0.9ec1fb96.js",
|
||||||
"build/1.2890d91a.js",
|
"build/1.2890d91a.js",
|
||||||
"build/app.2ee3c27f.js"
|
"build/app.78dd5afe.js"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"build/app.fb1d5bab.css"
|
"build/app.fb1d5bab.css"
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
"build/runtime.098eaae1.js": "sha384-xNNrNinl64G3nCUrIskgSjU0mUXXCB9lj6XCSInBTwxSKXk8uTMafnLHtdWdIGtd",
|
"build/runtime.098eaae1.js": "sha384-xNNrNinl64G3nCUrIskgSjU0mUXXCB9lj6XCSInBTwxSKXk8uTMafnLHtdWdIGtd",
|
||||||
"build/0.9ec1fb96.js": "sha384-1dI1TIwKkV71L1OH+DnDqaG1su73sfoXwMVzfTuAEIg0HgVImtDf01RtbASXV7yK",
|
"build/0.9ec1fb96.js": "sha384-1dI1TIwKkV71L1OH+DnDqaG1su73sfoXwMVzfTuAEIg0HgVImtDf01RtbASXV7yK",
|
||||||
"build/1.2890d91a.js": "sha384-r7OpYErcdJM7NmHiLm3n6J144cfkYc57YYAKn/QabksGh/Rd+tpcy6/kLwpVSD0b",
|
"build/1.2890d91a.js": "sha384-r7OpYErcdJM7NmHiLm3n6J144cfkYc57YYAKn/QabksGh/Rd+tpcy6/kLwpVSD0b",
|
||||||
"build/app.2ee3c27f.js": "sha384-YyGA9sqAqi7lk0IYrAj5E2CQZGZbMQuSCv2Auz7fbjxcuRJvh9hOWkV6r3qOJKNA",
|
"build/app.78dd5afe.js": "sha384-KpTVnYZDP5kIzX3JpMOeKw5qcbuNPtIqQeUmcGLmeXqVBTQeP4K/I5B6mZEx8nIq",
|
||||||
"build/app.fb1d5bab.css": "sha384-b8s0budBJh3JWWMyOZ08KKAx/Ukl0GWMX/o5yD87UL5SAq5datSu8vuzTS0cnA6T",
|
"build/app.fb1d5bab.css": "sha384-b8s0budBJh3JWWMyOZ08KKAx/Ukl0GWMX/o5yD87UL5SAq5datSu8vuzTS0cnA6T",
|
||||||
"build/invoice.74279541.js": "sha384-2BXic5Sgorf2tXai6zSAN4wLY2dbg06L03/xMKW6itMcszvtnRArKzfBh6DNcF3f",
|
"build/invoice.74279541.js": "sha384-2BXic5Sgorf2tXai6zSAN4wLY2dbg06L03/xMKW6itMcszvtnRArKzfBh6DNcF3f",
|
||||||
"build/invoice.13d8ef4e.css": "sha384-B6RN/wZJToSBCZk2JeLokIqWEhbh+Eb9arYbt9dM+YoC2Z6PnCeTwTqSGyexWWJh",
|
"build/invoice.13d8ef4e.css": "sha384-B6RN/wZJToSBCZk2JeLokIqWEhbh+Eb9arYbt9dM+YoC2Z6PnCeTwTqSGyexWWJh",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"build/1.2890d91a.js": "build/1.2890d91a.js",
|
"build/1.2890d91a.js": "build/1.2890d91a.js",
|
||||||
"build/2.42abdacc.js": "build/2.42abdacc.js",
|
"build/2.42abdacc.js": "build/2.42abdacc.js",
|
||||||
"build/app.css": "build/app.fb1d5bab.css",
|
"build/app.css": "build/app.fb1d5bab.css",
|
||||||
"build/app.js": "build/app.2ee3c27f.js",
|
"build/app.js": "build/app.78dd5afe.js",
|
||||||
"build/calendar.css": "build/calendar.1408f57e.css",
|
"build/calendar.css": "build/calendar.1408f57e.css",
|
||||||
"build/calendar.js": "build/calendar.070aab88.js",
|
"build/calendar.js": "build/calendar.070aab88.js",
|
||||||
"build/chart.js": "build/chart.34d60a88.js",
|
"build/chart.js": "build/chart.34d60a88.js",
|
||||||
|
|||||||
@@ -133,8 +133,7 @@
|
|||||||
<ul class="dropdown-menu"
|
<ul class="dropdown-menu"
|
||||||
data-api="{{ path('active_timesheet') }}"
|
data-api="{{ path('active_timesheet') }}"
|
||||||
data-href="{{ path('stop_timesheet', {'id' : '000'}) }}"
|
data-href="{{ path('stop_timesheet', {'id' : '000'}) }}"
|
||||||
data-icon="{{ 'stop-small'|icon }}"
|
data-icon="{{ 'stop-small'|icon }}">
|
||||||
data-format="{{ get_format_duration() }}">
|
|
||||||
<li class="header">
|
<li class="header">
|
||||||
{{ 'active.entries'|trans }}
|
{{ 'active.entries'|trans }}
|
||||||
</li>
|
</li>
|
||||||
@@ -149,7 +148,7 @@
|
|||||||
<h4>
|
<h4>
|
||||||
<span>{{ entry.activity.name }}</span>
|
<span>{{ entry.activity.name }}</span>
|
||||||
<small>
|
<small>
|
||||||
<span data-title="true" data-since="{{ entry.begin.format(constant('DATE_ISO8601')) }}" data-format="{{ get_format_duration() }}">{{ entry|duration }}</span>
|
<span data-title="true" data-since="{{ entry.begin.format(constant('DATE_ISO8601')) }}">{{ entry|duration }}</span>
|
||||||
</small>
|
</small>
|
||||||
</h4>
|
</h4>
|
||||||
<p>{{ entry.project.name }} ({{ entry.project.customer.name }})</p>
|
<p>{{ entry.project.name }} ({{ entry.project.customer.name }})</p>
|
||||||
@@ -276,6 +275,7 @@
|
|||||||
window.addEventListener('load', function() {
|
window.addEventListener('load', function() {
|
||||||
var loader = new KimaiWebLoader(
|
var loader = new KimaiWebLoader(
|
||||||
{
|
{
|
||||||
|
formatDuration: '{{ get_format_duration() }}',
|
||||||
login: '{{ path('fos_user_security_login') }}',
|
login: '{{ path('fos_user_security_login') }}',
|
||||||
locale: '{{ app.request.locale }}',
|
locale: '{{ app.request.locale }}',
|
||||||
first_dow_iso: {{ iso_day_by_name(app.user.firstDayOfWeek) }},
|
first_dow_iso: {{ iso_day_by_name(app.user.firstDayOfWeek) }},
|
||||||
|
|||||||
@@ -197,6 +197,7 @@
|
|||||||
|
|
||||||
let kimai = event.detail.kimai;
|
let kimai = event.detail.kimai;
|
||||||
let API = kimai.getPlugin('api');
|
let API = kimai.getPlugin('api');
|
||||||
|
let DATES = kimai.getPlugin('date');
|
||||||
jQuery('{{ calendarSelector }}').fullCalendar({
|
jQuery('{{ calendarSelector }}').fullCalendar({
|
||||||
themeSystem: 'bootstrap3',
|
themeSystem: 'bootstrap3',
|
||||||
defaultView: '{{ app.user.getPreferenceValue('calendar.initial_view') }}',
|
defaultView: '{{ app.user.getPreferenceValue('calendar.initial_view') }}',
|
||||||
@@ -338,15 +339,21 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
],
|
],
|
||||||
eventRender: function(eventObj, $el) {
|
eventRender: function(eventObj, $el, view) {
|
||||||
{# don't show popover for google calendar #}
|
{# don't show popover for google calendar #}
|
||||||
if (eventObj.source.ajaxSettings !== undefined) {
|
if (eventObj.source.ajaxSettings !== undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
{# or when an event is dragged or resized #}
|
{# or when an event is dragged or resized #}
|
||||||
if (!showPopover()) {
|
if (!showPopover()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (view.name !== 'month' ) {
|
||||||
|
jQuery(".fc-dailytotal").text(DATES.formatSeconds(0)).data('seconds', 0).data('ids', '');
|
||||||
|
}
|
||||||
|
|
||||||
hidePopover();
|
hidePopover();
|
||||||
$el.popover({
|
$el.popover({
|
||||||
title: renderEventPopoverTitle(eventObj),
|
title: renderEventPopoverTitle(eventObj),
|
||||||
@@ -357,78 +364,117 @@
|
|||||||
html: true
|
html: true
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
{% if not is_punch_mode and is_granted('create_own_timesheet') %}
|
viewRender: function(view, element) {
|
||||||
dayClick: function(date, jsEvent, view) {
|
if (view.name === 'month') {
|
||||||
{#
|
|
||||||
Day-clicks are always triggered, unless a selection was created.
|
|
||||||
So clicking in a day (month view) or any slot (week and day view) will trigger a dayClick
|
|
||||||
BEFORE triggering a select - make sure not two create dialogs are requested
|
|
||||||
#}
|
|
||||||
if (view.type !== 'month') {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let createUrl = '{{ path('timesheet_create') }}?begin=' + date.format();
|
{# allowed in agendaWeek and agendaDay #}
|
||||||
kimai.getPlugin('modal').openUrlInModal(createUrl);
|
jQuery(".fc-day-header").each(function (key, val) {
|
||||||
|
var $this = jQuery(this);
|
||||||
|
var dateYMD = $this.attr("data-date");
|
||||||
|
$this.append('<div class="fc-dailytotal" data-seconds="0" data-ids="" id="dailytotal-' + dateYMD + '">'+DATES.formatSeconds(0)+'</div>');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
selectable: true,
|
eventAfterRender: function(event, element, view) {
|
||||||
select: function(start, end, jsEvent, view) {
|
{# allowed in agendaWeek and agendaDay #}
|
||||||
if(view.type === 'month') {
|
if (view.name === 'month') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{# TODO calculate duration for running entries #}
|
||||||
|
if (event.end === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{# TODO split day entries are calculated only for the begin date #}
|
||||||
|
var $element = jQuery("#dailytotal-" + moment(event.start).format("YYYY-MM-DD"));
|
||||||
|
var ids = $element.data('ids');
|
||||||
|
if (ids === null) {
|
||||||
|
ids = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ids.indexOf(event.id) !== -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var prev = $element.data('seconds');
|
||||||
|
var duration = prev + ((event.end - event.start) / 1000);
|
||||||
|
$element.data('seconds', duration);
|
||||||
|
$element.data('ids', event.id + ' ' + ids);
|
||||||
|
$element.text(DATES.formatSeconds(duration));
|
||||||
|
},
|
||||||
|
{% if not is_punch_mode and is_granted('create_own_timesheet') %}
|
||||||
|
dayClick: function(date, jsEvent, view) {
|
||||||
{#
|
{#
|
||||||
Multi-day clicks are NOT allowed in the month view, as simple day clicks would also trigger
|
Day-clicks are always triggered, unless a selection was created.
|
||||||
a select - there is no way to distinguish a simple click and a two day selection
|
So clicking in a day (month view) or any slot (week and day view) will trigger a dayClick
|
||||||
|
BEFORE triggering a select - make sure not two create dialogs are requested
|
||||||
#}
|
#}
|
||||||
return;
|
if (view.type !== 'month') {
|
||||||
}
|
return;
|
||||||
let createUrl = '{{ path('timesheet_create') }}' + '?from=' + start.format() + '&to=' + end.format();
|
}
|
||||||
kimai.getPlugin('modal').openUrlInModal(createUrl);
|
|
||||||
},
|
|
||||||
{% endif %}
|
|
||||||
{% if is_granted('edit_own_timesheet') %}
|
|
||||||
eventClick: function(eventObj, jsEvent, view) {
|
|
||||||
if (eventObj.source.ajaxSettings !== undefined) {
|
|
||||||
jsEvent.preventDefault();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let editUrl = '{{ path('timesheet_edit', {id: '-XX-'}) }}'.replace('-XX-', eventObj.id);
|
|
||||||
kimai.getPlugin('modal').openUrlInModal(editUrl);
|
|
||||||
},
|
|
||||||
{% if not is_punch_mode %}
|
|
||||||
editable: true,
|
|
||||||
eventDragStart: function(event, jsEvent, ui, view) {
|
|
||||||
deactivatePopover();
|
|
||||||
},
|
|
||||||
eventDragStop: function(event, jsEvent, ui, view) {
|
|
||||||
activatePopover();
|
|
||||||
{% if is_granted('delete_own_timesheet') %}
|
|
||||||
var trash = jQuery('.fc-deleteButton-button');
|
|
||||||
var offset = trash.offset();
|
|
||||||
|
|
||||||
if (jsEvent.pageX >= offset.left && jsEvent.pageX<= (offset.left + trash.outerWidth(true)) &&
|
let createUrl = '{{ path('timesheet_create') }}?begin=' + date.format();
|
||||||
jsEvent.pageY >= offset.top && jsEvent.pageY <= (offset.top + trash.outerHeight(true))) {
|
kimai.getPlugin('modal').openUrlInModal(createUrl);
|
||||||
// FIXME confirm delete
|
|
||||||
API.delete(
|
|
||||||
'{{ path('delete_timesheet', {'id': '__xxx__'}) }}'.replace('__xxx__', event.id),
|
|
||||||
function () {
|
|
||||||
kimai.getPlugin('alert').success('action.delete.success');
|
|
||||||
jQuery('{{ calendarSelector }}').fullCalendar('removeEvents', event._id);
|
|
||||||
}, function () {
|
|
||||||
kimai.getPlugin('alert').success('action.delete.error');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
},
|
},
|
||||||
eventDrop: changeHandler,
|
selectable: true,
|
||||||
eventResizeStart: function(event, jsEvent, ui, view) {
|
select: function(start, end, jsEvent, view) {
|
||||||
deactivatePopover();
|
if(view.type === 'month') {
|
||||||
|
{#
|
||||||
|
Multi-day clicks are NOT allowed in the month view, as simple day clicks would also trigger
|
||||||
|
a select - there is no way to distinguish a simple click and a two day selection
|
||||||
|
#}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let createUrl = '{{ path('timesheet_create') }}' + '?from=' + start.format() + '&to=' + end.format();
|
||||||
|
kimai.getPlugin('modal').openUrlInModal(createUrl);
|
||||||
},
|
},
|
||||||
eventResizeStop: function(event, jsEvent, ui, view) {
|
|
||||||
activatePopover();
|
|
||||||
},
|
|
||||||
eventResize: changeHandler,
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% if is_granted('edit_own_timesheet') %}
|
||||||
|
eventClick: function(eventObj, jsEvent, view) {
|
||||||
|
if (eventObj.source.ajaxSettings !== undefined) {
|
||||||
|
jsEvent.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let editUrl = '{{ path('timesheet_edit', {id: '-XX-'}) }}'.replace('-XX-', eventObj.id);
|
||||||
|
kimai.getPlugin('modal').openUrlInModal(editUrl);
|
||||||
|
},
|
||||||
|
{% if not is_punch_mode %}
|
||||||
|
editable: true,
|
||||||
|
eventDragStart: function(event, jsEvent, ui, view) {
|
||||||
|
deactivatePopover();
|
||||||
|
},
|
||||||
|
eventDragStop: function(event, jsEvent, ui, view) {
|
||||||
|
activatePopover();
|
||||||
|
{% if is_granted('delete_own_timesheet') %}
|
||||||
|
var trash = jQuery('.fc-deleteButton-button');
|
||||||
|
var offset = trash.offset();
|
||||||
|
|
||||||
|
if (jsEvent.pageX >= offset.left && jsEvent.pageX<= (offset.left + trash.outerWidth(true)) &&
|
||||||
|
jsEvent.pageY >= offset.top && jsEvent.pageY <= (offset.top + trash.outerHeight(true))) {
|
||||||
|
API.delete(
|
||||||
|
'{{ path('delete_timesheet', {'id': '__xxx__'}) }}'.replace('__xxx__', event.id),
|
||||||
|
function () {
|
||||||
|
kimai.getPlugin('alert').success('action.delete.success');
|
||||||
|
jQuery('{{ calendarSelector }}').fullCalendar('removeEvents', event._id);
|
||||||
|
}, function () {
|
||||||
|
kimai.getPlugin('alert').success('action.delete.error');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
},
|
||||||
|
eventDrop: changeHandler,
|
||||||
|
eventResizeStart: function(event, jsEvent, ui, view) {
|
||||||
|
deactivatePopover();
|
||||||
|
},
|
||||||
|
eventResizeStop: function(event, jsEvent, ui, view) {
|
||||||
|
activatePopover();
|
||||||
|
},
|
||||||
|
eventResize: changeHandler,
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
});
|
});
|
||||||
var trashBtn = jQuery('.fc-deleteButton-button');
|
var trashBtn = jQuery('.fc-deleteButton-button');
|
||||||
trashBtn.html('<span class="text-danger"><i class="{{ 'trash'|icon }} text-danger"></i> ' + trashBtn.text() + '</span>');
|
trashBtn.html('<span class="text-danger"><i class="{{ 'trash'|icon }} text-danger"></i> ' + trashBtn.text() + '</span>');
|
||||||
|
|||||||
@@ -6,8 +6,7 @@
|
|||||||
<ul class="dropdown-menu"
|
<ul class="dropdown-menu"
|
||||||
data-api="{{ path('active_timesheet') }}"
|
data-api="{{ path('active_timesheet') }}"
|
||||||
data-href="{{ path('stop_timesheet', {'id' : '000'}) }}"
|
data-href="{{ path('stop_timesheet', {'id' : '000'}) }}"
|
||||||
data-icon="{{ 'stop-small'|icon }}"
|
data-icon="{{ 'stop-small'|icon }}">
|
||||||
data-format="{{ get_format_duration() }}">
|
|
||||||
<li class="header">
|
<li class="header">
|
||||||
{{ 'active.entries'|trans }}
|
{{ 'active.entries'|trans }}
|
||||||
</li>
|
</li>
|
||||||
@@ -22,7 +21,7 @@
|
|||||||
<h4>
|
<h4>
|
||||||
<span>{{ entry.activity.name }}</span>
|
<span>{{ entry.activity.name }}</span>
|
||||||
<small>
|
<small>
|
||||||
<span data-title="true" data-since="{{ entry.begin.format(constant('DATE_ISO8601')) }}" data-format="{{ get_format_duration() }}">{{ entry|duration }}</span>
|
<span data-title="true" data-since="{{ entry.begin.format(constant('DATE_ISO8601')) }}">{{ entry|duration }}</span>
|
||||||
</small>
|
</small>
|
||||||
</h4>
|
</h4>
|
||||||
<p>{{ entry.project.name }} ({{ entry.project.customer.name }})</p>
|
<p>{{ entry.project.name }} ({{ entry.project.customer.name }})</p>
|
||||||
|
|||||||
@@ -119,7 +119,7 @@
|
|||||||
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'duration') }}">{{ entry.duration|duration }}</td>
|
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'duration') }}">{{ entry.duration|duration }}</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'duration') }}">
|
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'duration') }}">
|
||||||
<i data-since="{{ entry.begin.format(constant('DATE_ISO8601')) }}" data-format="{{ get_format_duration() }}">{{ entry|duration }}</i>
|
<i data-since="{{ entry.begin.format(constant('DATE_ISO8601')) }}">{{ entry|duration }}</i>
|
||||||
</td>
|
</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ class LayoutControllerTest extends ControllerBaseTest
|
|||||||
self::assertStringContainsString('data-api="', $content);
|
self::assertStringContainsString('data-api="', $content);
|
||||||
self::assertStringContainsString('data-href="', $content);
|
self::assertStringContainsString('data-href="', $content);
|
||||||
self::assertStringContainsString('data-icon=', $content);
|
self::assertStringContainsString('data-icon=', $content);
|
||||||
self::assertStringContainsString('data-format=', $content);
|
|
||||||
self::assertStringContainsString('<ul class="menu">', $content);
|
self::assertStringContainsString('<ul class="menu">', $content);
|
||||||
self::assertStringContainsString('<li class="messages-menu-empty" style="">', $content);
|
self::assertStringContainsString('<li class="messages-menu-empty" style="">', $content);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user