fix toolbar requests for empty choice (#758)

This commit is contained in:
Kevin Papst
2019-05-05 08:31:13 +02:00
committed by GitHub
parent 6e224c63ef
commit 80af3fb010
12 changed files with 69 additions and 32 deletions

View File

@@ -67,10 +67,18 @@ $(function() {
var $form = $('.toolbar form');
var loading = '<div class="overlay"><i class="fas fa-sync fa-spin"></i></div>';
$('section.content').append(loading);
// remove the empty fields to prevent errors
var formData = $('.toolbar form :input')
.filter(function(index, element) {
return $(element).val() != '';
})
.serialize();
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: $form.serialize(),
data: formData,
success: function(html) {
$('section.content').replaceWith(
$(html).find('section.content')
@@ -101,9 +109,26 @@ $(function() {
);
},
activateApiSelects: function(selector) {
const self = this;
$('body').on('change', selector, function(event) {
var apiUrl = $(this).attr('data-api-url').replace('-s-', $(this).val());
var targetSelect = $(this).attr('data-related-select');
let apiUrl = $(this).attr('data-api-url').replace('-s-', $(this).val());
const targetSelect = '#' + $(this).attr('data-related-select');
// if the related target select does not exist, we do not need to load the related data
if ($(targetSelect).length === 0) {
return;
}
if ($(this).val() === '') {
if ($(this).attr('data-empty-url') === undefined) {
self.updateSelect(targetSelect, {});
$(targetSelect).attr('disabled', 'disabled');
return;
}
apiUrl = $(this).attr('data-empty-url').replace('-s-', $(this).val());
}
$(targetSelect).removeAttr('disabled');
$.ajax({
url: apiUrl,
@@ -114,29 +139,31 @@ $(function() {
method: 'GET',
dataType: 'json',
success: function(data){
var selectName = '#' + targetSelect;
var $select = $(selectName);
var $emptyOption = $(selectName + ' option[value=""]');
$select.find('option').remove().end().find('optgroup').remove().end();
if ($emptyOption.length !== 0) {
$select.append('<option value="">' + $emptyOption.text() + '</option>');
}
$.each(data, function(i, obj) {
$select.append('<option value="' + obj.id + '">' + obj.name + '</option>');
});
// if we don't trigger the change, the other selects won't be resetted
$select.trigger('change');
// if the beta test kimai.theme.select_type is active, this will tell the selects to refresh
$('.selectpicker').selectpicker('refresh');
self.updateSelect(targetSelect, data);
}
});
});
},
updateSelect: function(selectName, data) {
var $select = $(selectName);
var $emptyOption = $(selectName + ' option[value=""]');
$select.find('option').remove().end().find('optgroup').remove().end();
if ($emptyOption.length !== 0) {
$select.append('<option value="">' + $emptyOption.text() + '</option>');
}
$.each(data, function(i, obj) {
$select.append('<option value="' + obj.id + '">' + obj.name + '</option>');
});
// if we don't trigger the change, the other selects won't be resetted
$select.trigger('change');
// if the beta test kimai.theme.select_type is active, this will tell the selects to refresh
$('.selectpicker').selectpicker('refresh');
},
activateDatePicker: function(selector) {
$(selector + ' input[data-datepickerenable="on"]').each(function(index) {
var localeFormat = $(this).data('format');

View File

@@ -10,7 +10,7 @@
*/
$(document).ready(function () {
/* Submit the pagination including the toolbar filters */
// This catches all clicks on the pagination and prevents the default action, as we want to relad the page via JS
$('body').on('click', 'div.navigation ul.pagination li a', function(event) {
var $pager = $(".toolbar form input[name='page']");
if ($pager.length === 0) {
@@ -25,6 +25,8 @@ $(document).ready(function () {
return false;
});
// Reset the page if any other value is changed, otherwise we might end up with a limited set
// of data which does not support the given page - and it would be just wrong to stay in the same page
$('.toolbar form input').change(function (event) {
switch (event.target.id) {
case 'page':

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{
"build/app.js": "./app.js?[contenthash]",
"build/app.css": "./app.css?5748431b597376d6472e58cf92e2c0f5",
"build/app.css": "./app.css?361d4520765f893b9b0fb94bc9f761c1",
"build/fonts/fa-solid-900.woff2": "./fonts/fa-solid-900.woff2?e8a92a29",
"build/images/fa-solid-900.svg": "./images/fa-solid-900.svg?666a82cb",
"build/images/glyphicons-halflings-regular.svg": "./images/glyphicons-halflings-regular.svg?89889688",

View File

@@ -97,7 +97,7 @@ class ActivityController extends BaseApiController
$query->setOrderGlobalsFirst(false);
}
if (null !== ($project = $paramFetcher->get('project'))) {
if (!empty($project = $paramFetcher->get('project'))) {
$query->setProject($project);
}

View File

@@ -88,7 +88,7 @@ class ProjectController extends BaseApiController
$query->setOrderBy($orderBy);
}
if (null !== ($customer = $paramFetcher->get('customer'))) {
if (!empty($customer = $paramFetcher->get('customer'))) {
$query->setCustomer($customer);
}

View File

@@ -111,15 +111,15 @@ class TimesheetController extends BaseApiController
$query->setUser($user);
}
if (null !== ($customer = $paramFetcher->get('customer'))) {
if (!empty($customer = $paramFetcher->get('customer'))) {
$query->setCustomer($customer);
}
if (null !== ($project = $paramFetcher->get('project'))) {
if (!empty($project = $paramFetcher->get('project'))) {
$query->setProject($project);
}
if (null !== ($activity = $paramFetcher->get('activity'))) {
if (!empty($activity = $paramFetcher->get('activity'))) {
$query->setActivity($activity);
}

View File

@@ -1108,7 +1108,7 @@ class KimaiImporterCommand extends Command
$io->error('Found invalid mapped project - activity combinations in these old timesheet recors: ' . implode(',', $errors['projectActivityMismatch']));
}
if ($failed > 0) {
$io->error(sprintf('Failed importing %s timesheet records', count($failed)));
$io->error(sprintf('Failed importing %s timesheet records', $failed));
}
return $counter;

View File

@@ -77,6 +77,12 @@ class SelectWithApiDataExtension extends AbstractTypeExtension
'data-related-select' => $formPrefix . $apiData['select'],
'data-api-url' => $this->router->generate($apiData['route'], $apiData['route_params']),
]);
if (isset($apiData['empty_route_params'])) {
$view->vars['attr'] = array_merge($view->vars['attr'], [
'data-empty-url' => $this->router->generate($apiData['route'], $apiData['empty_route_params']),
]);
}
}
/**

View File

@@ -129,6 +129,7 @@ abstract class AbstractToolbarForm extends AbstractType
'required' => false,
'activity_enabled' => true,
'choices' => [],
'disabled' => true,
]);
$builder->addEventListener(

View File

@@ -74,6 +74,7 @@ class ProjectType extends AbstractType
'select' => 'activity',
'route' => 'get_activities',
'route_params' => ['project' => '-s-', 'orderBy' => 'name', 'visible' => $options['activity_visibility']],
'empty_route_params' => ['globals' => 'true', 'orderBy' => 'name', 'visible' => $options['activity_visibility']],
];
}