replaced delete confirm dialog with modal (#638)

This commit is contained in:
Kevin Papst
2019-03-12 23:24:22 +01:00
committed by GitHub
parent 46655ad462
commit f4d53e9006
43 changed files with 303 additions and 109 deletions

View File

@@ -44,19 +44,12 @@ $(function() {
// auto hide success message after x seconds, as they are just meant as quick feedback and
// not as a permanent source of information
if ($.kimai.settings['alertSuccessAutoHide'] > 0) {
setTimeout(
function() {
$('div.alert-success').alert('close');
},
$.kimai.settings['alertSuccessAutoHide']
);
}
// ask before a delete call is executed
$('body').on('click', 'a.btn-trash', function (event) {
return confirm($.kimai.settings['confirmDelete']);
});
setTimeout(
function() {
$('div.alert-success').alert('close');
},
5000
);
// compound field in toolbar
this.activateDateRangePicker('.content-wrapper');
@@ -107,6 +100,7 @@ $(function() {
});
},
reloadDatatableWithToolbarFilter: function() {
// TODO check if toolbar form is present, if not, reload current URL
var $form = $('.toolbar form');
var loading = '<div class="overlay"><i class="fas fa-sync fa-spin"></i></div>';
$('section.content').append(loading);
@@ -230,6 +224,8 @@ $(function() {
// load new form from given content
if ($(html).find('#form_modal .modal-content').length > 0 ) {
// switch classes, in case the modal type changed
$('#remote_form_modal').attr('class', $(html).find('#form_modal').attr('class'));
// TODO cleanup widgets before replacing the content?
$('#remote_form_modal .modal-content').replaceWith(
$(html).find('#form_modal .modal-content')
@@ -312,8 +308,6 @@ $(function() {
// default values
$.kimai.defaults = {
locale: 'en',
alertSuccessAutoHide: 5000,
confirmDelete: 'Really delete?',
today: 'Today',
yesterday: 'Yesterday',
apply: 'Apply',

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
{
"build/app.js": "./app.js?689ff5ff33eeac75779e",
"build/app.js": "./app.js?2adac3fa8d223ed843ed",
"build/app.css": "./app.css?d1c5aa3942706f7bffb181e234e112de",
"build/images/blue@2x.png": "./images/blue@2x.png?2694acfd",
"build/images/blue.png": "./images/blue.png?96f8a905",

View File

@@ -603,7 +603,7 @@ class KimaiImporterCommand extends Command
->setFax($oldCustomer['fax'])
->setHomepage($oldCustomer['homepage'])
->setMobile($oldCustomer['mobile'])
->setMail($oldCustomer['mail'])
->setEmail($oldCustomer['mail'])
->setPhone($oldCustomer['phone'])
->setContact($oldCustomer['contact'])
->setAddress($oldCustomer['street'] . PHP_EOL . $oldCustomer['zipcode'] . ' ' . $oldCustomer['city'])

View File

@@ -135,12 +135,12 @@ class ActivityController extends AbstractController
$deleteForm->handleRequest($request);
if (0 == $stats->getRecordAmount() || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
if ($deleteForm->isSubmitted() && $deleteForm->isValid()) {
try {
$this->getRepository()->deleteActivity($activity, $deleteForm->get('activity')->getData());
$this->flashSuccess('action.delete.success');
} catch (ORMException $ex) {
$this->flashError('action.delete.error');
$this->flashError('action.delete.error', ['%reason%' => $ex->getMessage()]);
}
return $this->redirectToRoute('admin_activity');

View File

@@ -146,12 +146,12 @@ class CustomerController extends AbstractController
$deleteForm->handleRequest($request);
if (0 == $stats->getRecordAmount() || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
if ($deleteForm->isSubmitted() && $deleteForm->isValid()) {
try {
$this->getRepository()->deleteCustomer($customer, $deleteForm->get('customer')->getData());
$this->flashSuccess('action.delete.success');
} catch (ORMException $ex) {
$this->flashError('action.delete.error');
$this->flashError('action.delete.error', ['%reason%' => $ex->getMessage()]);
}
return $this->redirectToRoute('admin_customer');

View File

@@ -133,12 +133,12 @@ class ProjectController extends AbstractController
$deleteForm->handleRequest($request);
if (0 == $stats->getRecordAmount() || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
if ($deleteForm->isSubmitted() && $deleteForm->isValid()) {
try {
$this->getRepository()->deleteProject($project, $deleteForm->get('project')->getData());
$this->flashSuccess('action.delete.success');
} catch (ORMException $ex) {
$this->flashError('action.delete.error');
$this->flashError('action.delete.error', ['%reason%' => $ex->getMessage()]);
}
return $this->redirectToRoute('admin_project');

View File

@@ -13,6 +13,7 @@ use App\Entity\Timesheet;
use App\Form\TimesheetEditForm;
use App\Form\Toolbar\TimesheetToolbarForm;
use App\Repository\Query\TimesheetQuery;
use Doctrine\ORM\ORMException;
use Pagerfanta\Pagerfanta;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Request;
@@ -228,17 +229,28 @@ class TimesheetController extends AbstractController
*/
public function deleteAction(Timesheet $entry, Request $request)
{
try {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($entry);
$entityManager->flush();
$deleteForm = $this->createFormBuilder()
->setAction($this->generateUrl('timesheet_delete', ['id' => $entry->getId()]))
->setMethod('POST')
->getForm();
$this->flashSuccess('action.delete.success');
} catch (\Exception $ex) {
$this->flashError('action.delete.error', ['%reason%' => $ex->getMessage()]);
$deleteForm->handleRequest($request);
if ($deleteForm->isSubmitted() && $deleteForm->isValid()) {
try {
$this->getRepository()->delete($entry);
$this->flashSuccess('action.delete.success');
} catch (ORMException $ex) {
$this->flashError('action.delete.error', ['%reason%' => $ex->getMessage()]);
}
return $this->redirectToRoute('timesheet');
}
return $this->redirectToRoute('timesheet_paginated', ['page' => $request->get('page', 1)]);
return $this->render('timesheet/delete.html.twig', [
'timesheet' => $entry,
'form' => $deleteForm->createView(),
]);
}
/**

View File

@@ -13,6 +13,7 @@ use App\Entity\Timesheet;
use App\Form\TimesheetEditForm;
use App\Form\Toolbar\TimesheetToolbarForm;
use App\Repository\Query\TimesheetQuery;
use Doctrine\ORM\ORMException;
use Pagerfanta\Pagerfanta;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Request;
@@ -152,17 +153,28 @@ class TimesheetTeamController extends AbstractController
*/
public function deleteAction(Timesheet $entry, Request $request)
{
try {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($entry);
$entityManager->flush();
$deleteForm = $this->createFormBuilder()
->setAction($this->generateUrl('admin_timesheet_delete', ['id' => $entry->getId()]))
->setMethod('POST')
->getForm();
$this->flashSuccess('action.delete.success');
} catch (\Exception $ex) {
$this->flashError('action.delete.error', ['%reason%' => $ex->getMessage()]);
$deleteForm->handleRequest($request);
if ($deleteForm->isSubmitted() && $deleteForm->isValid()) {
try {
$this->getRepository()->delete($entry);
$this->flashSuccess('action.delete.success');
} catch (ORMException $ex) {
$this->flashError('action.delete.error', ['%reason%' => $ex->getMessage()]);
}
return $this->redirectToRoute('admin_timesheet');
}
return $this->redirectToRoute('admin_timesheet_paginated', ['page' => $request->get('page', 1)]);
return $this->render('timesheet-team/delete.html.twig', [
'timesheet' => $entry,
'form' => $deleteForm->createView(),
]);
}
/**

View File

@@ -147,7 +147,7 @@ class UserController extends AbstractController
$deleteForm->handleRequest($request);
if (0 == $stats->getRecordsTotal() || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
if ($deleteForm->isSubmitted() && $deleteForm->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($userToDelete);
$entityManager->flush();

View File

@@ -82,6 +82,7 @@ class ThemeEvent extends Event
public function setPayload($payload)
{
$this->payload = $payload;
return $this;
}
}

View File

@@ -30,6 +30,18 @@ class TimesheetRepository extends AbstractRepository
public const STATS_QUERY_ACTIVE = 'active';
public const STATS_QUERY_MONTHLY = 'monthly';
/**
* @param Timesheet $timesheet
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function delete(Timesheet $timesheet)
{
$entityManager = $this->getEntityManager();
$entityManager->remove($timesheet);
$entityManager->flush();
}
/**
* @param Timesheet $timesheet
* @throws \Doctrine\ORM\ORMException

View File

@@ -79,5 +79,4 @@ class EventExtensions extends AbstractExtension
return $themeEvent;
}
}

View File

@@ -1,6 +1,4 @@
{% 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' %}
{% import "macros/actions.html.twig" as actions %}
{% block page_title %}{{ 'admin_activity.title'|trans }}{% endblock %}
@@ -9,6 +7,8 @@
{% block main %}
{% set inUse = (stats.recordAmount > 0) %}
{% set params = {
'%activity%': '<strong>' ~ activity.name ~ '</strong>',
'%project%': '<strong>-</strong>',
@@ -23,9 +23,11 @@
'%customer%': '<strong>' ~ activity.project.customer.name ~ '</strong>',
}) %}
{% endif %}
{{ include('default/_form_delete.html.twig', {
{{ include(app.request.xmlHttpRequest ? 'default/_form_delete_modal.html.twig' : 'default/_form_delete.html.twig', {
'message': "admin_activity.delete_confirm"|trans(params)|raw,
'form': form,
'used': inUse,
'back': path('admin_activity')
}) }}

View File

@@ -113,7 +113,6 @@
$(document).ready(function () {
$.kimai.init({
locale: '{{ app.request.locale }}',
confirmDelete: '{{ 'confirm.delete'|trans }}',
apply: '{{ 'daterangepicker.apply'|trans({}, 'daterangepicker') }}',
cancel: '{{ 'daterangepicker.cancel'|trans({}, 'daterangepicker') }}',
today: '{{ 'daterangepicker.today'|trans({}, 'daterangepicker') }}',

View File

@@ -1,6 +1,4 @@
{% 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' %}
{% import "macros/actions.html.twig" as actions %}
{% block page_title %}{{ 'admin_customer.title'|trans }}{% endblock %}
@@ -9,6 +7,8 @@
{% block main %}
{% set inUse = (stats.recordAmount > 0) %}
{% set params = {
'%activity%': '<strong>' ~ stats.activityAmount ~ '</strong>',
'%project%': '<strong>' ~ stats.projectAmount ~ '</strong>',
@@ -17,9 +17,10 @@
'%duration%': '<strong>' ~ stats.recordDuration|duration ~ '</strong>'
} %}
{{ include('default/_form_delete.html.twig', {
{{ include(app.request.xmlHttpRequest ? 'default/_form_delete_modal.html.twig' : 'default/_form_delete.html.twig', {
'message': "admin_customer.delete_confirm"|trans(params)|raw,
'form': form,
'used': inUse,
'back': path('admin_customer')
}) }}

View File

@@ -0,0 +1,24 @@
{% embed 'embeds/modal.html.twig' %}
{% block modal_id %}form_modal{% endblock %}
{% block modal_class %}{% if used %}modal-danger{% endif %}{% endblock %}
{% block modal_before %}{{ form_start(form) }}{% endblock %}
{% block modal_title %}
{{ title|default('confirm.delete'|trans) }}
{% endblock %}
{% block modal_body %}
{% if used is same as (false) %}
{{ 'delete.not_in_use'|trans }}
<div class="hidden">
{{ form_widget(form) }}
</div>
{% else %}
<p>{{ message|default('confirm.delete_message'|trans)|raw }}</p>
{{ form_widget(form) }}
{% endif %}
{% 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 {% if used %}btn-outline{% else %}btn-primary{% endif %} modal-form-save" data-loading-text="{{ 'action.delete'|trans }}..." id="{{ block('modal_id') }}_save">{{ 'action.delete'|trans }}</button>
{% endblock %}
{% block modal_end %}{{ form_end(form) }}{% endblock %}
{% endembed %}

View File

@@ -12,7 +12,7 @@
{% 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>
<button type="submit" class="btn btn-primary modal-form-save" data-loading-text="{{ 'action.save'|trans }}..." id="{{ block('modal_id') }}_save">{{ 'action.save'|trans }}</button>
{% endblock %}
{% block modal_end %}{{ form_end(form) }}{% endblock %}
{% endembed %}

View File

@@ -1,4 +1,4 @@
<div class="modal fade" id="{{ block('modal_id') }}" tabindex="-1" role="dialog" aria-labelledby="{{ block('modal_id') }}_label">
<div class="modal{% if block('modal_class') is defined %} {{ block('modal_class') }}{% endif %} 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 %}

View File

@@ -19,8 +19,8 @@
{% if is_granted('edit', activity) %}
{% set actions = actions|merge({'edit': path('admin_activity_edit', {'id': activity.id})}) %}
{% endif %}
{% if is_granted('delete', activity) %}
{% set actions = actions|merge({'trash': path('admin_activity_delete', {'id': activity.id})}) %}
{% if view == 'index' and is_granted('delete', activity) %}
{% set actions = actions|merge({'trash': {'url': path('admin_activity_delete', {'id': activity.id}), 'class': 'modal-ajax-form'}}) %}
{% endif %}
{% endif %}
@@ -59,8 +59,8 @@
{% if is_granted('view_activity') %}
{% set actions = actions|merge({'activity': path('admin_activity', {'customer': project.customer.id, 'project': project.id})}) %}
{% endif %}
{% if is_granted('delete', project) %}
{% set actions = actions|merge({'trash': path('admin_project_delete', {'id': project.id})}) %}
{% if view == 'index' and is_granted('delete', project) %}
{% set actions = actions|merge({'trash': {'url': path('admin_project_delete', {'id': project.id}), 'class': 'modal-ajax-form'}}) %}
{% endif %}
{% endif %}
@@ -99,8 +99,8 @@
{% if is_granted('view_project') %}
{% set actions = actions|merge({'project': path('admin_project', {'customer': customer.id})}) %}
{% endif %}
{% if is_granted('delete', customer) %}
{% set actions = actions|merge({'trash': path('admin_customer_delete', {'id': customer.id})}) %}
{% if view == 'index' and is_granted('delete', customer) %}
{% set actions = actions|merge({'trash': {'url': path('admin_customer_delete', {'id': customer.id}), 'class': 'modal-ajax-form'}}) %}
{% endif %}
{% endif %}
@@ -156,8 +156,8 @@
{% set actions = actions|merge({'edit': {'url': path('timesheet_edit', {'id': timesheet.id}), 'class': class}}) %}
{% endif %}
{% if is_granted('delete', timesheet) %}
{% set actions = actions|merge({'trash': path('timesheet_delete', {'id' : timesheet.id})}) %}
{% if view == 'index' and is_granted('delete', timesheet) %}
{% set actions = actions|merge({'trash': {'url': path('timesheet_delete', {'id' : timesheet.id}), 'class': 'modal-ajax-form'}}) %}
{% endif %}
{% endif %}
@@ -197,6 +197,7 @@
{% if not timesheet.end and is_granted('stop', timesheet) %}
{% set actions = actions|merge({'stop': path('admin_timesheet_stop', {'id' : timesheet.id})}) %}
{% endif %}
{% if is_granted('edit', timesheet) %}
{% set class = '' %}
{% if view != 'edit' %}
@@ -204,8 +205,9 @@
{% endif %}
{% set actions = actions|merge({'edit': {'url': path('admin_timesheet_edit', {'id': timesheet.id}), 'class': class}}) %}
{% endif %}
{% if is_granted('delete', timesheet) %}
{% set actions = actions|merge({'trash': path('admin_timesheet_delete', {'id' : timesheet.id})}) %}
{% if view == 'index' and is_granted('delete', timesheet) %}
{% set actions = actions|merge({'trash': {'url': path('admin_timesheet_delete', {'id' : timesheet.id}), 'class': 'modal-ajax-form'}}) %}
{% endif %}
{% endif %}

View File

@@ -1,6 +1,4 @@
{% 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' %}
{% import "macros/actions.html.twig" as actions %}
{% block page_title %}{{ 'admin_project.title'|trans }}{% endblock %}
@@ -9,6 +7,8 @@
{% block main %}
{% set inUse = (stats.recordAmount > 0) %}
{% set params = {
'%project%': '<strong>' ~ project.name ~ '</strong>',
'%customer%': '<strong>' ~ project.customer.name ~ '</strong>',
@@ -17,9 +17,10 @@
'%duration%': '<strong>' ~ stats.recordDuration|duration ~ '</strong>'
} %}
{{ include('default/_form_delete.html.twig', {
{{ include(app.request.xmlHttpRequest ? 'default/_form_delete_modal.html.twig' : 'default/_form_delete.html.twig', {
'message': "admin_project.delete_confirm"|trans(params)|raw,
'form': form,
'used': inUse,
'back': path('admin_project')
}) }}

View File

@@ -51,7 +51,7 @@
<i class="{{ 'help'|icon }} text-gray"></i>
</div>
<div class="menu-info">
<h4 class="control-sidebar-subheading">{{ 'help.title'|trans }}</h4>
<h4 class="control-sidebar-subheading">{{ 'home.help'|trans({}, 'sidebar') }}</h4>
</div>
</a>
</li>

View File

@@ -0,0 +1,17 @@
{% extends app.request.xmlHttpRequest ? 'form.html.twig' : 'base.html.twig' %}
{% import "macros/actions.html.twig" as actions %}
{% block page_title %}{{ 'admin_timesheet.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'admin_timesheet.subtitle'|trans }}{% endblock %}
{% block page_actions %}{{ actions.timesheet_team(timesheet, 'delete') }}{% endblock %}
{% block main %}
{{ include(app.request.xmlHttpRequest ? 'default/_form_delete_modal.html.twig' : 'default/_form_delete.html.twig', {
'message': "delete.not_in_use"|trans|raw,
'form': form,
'used': false,
'back': path('admin_timesheet')
}) }}
{% endblock %}

View File

@@ -0,0 +1,17 @@
{% extends app.request.xmlHttpRequest ? 'form.html.twig' : 'base.html.twig' %}
{% import "macros/actions.html.twig" as actions %}
{% block page_title %}{{ 'timesheet.title'|trans }}{% endblock %}
{% block page_subtitle %}{{ 'timesheet.subtitle'|trans }}{% endblock %}
{% block page_actions %}{{ actions.timesheet(timesheet, 'delete') }}{% endblock %}
{% block main %}
{{ include(app.request.xmlHttpRequest ? 'default/_form_delete_modal.html.twig' : 'default/_form_delete.html.twig', {
'message': "delete.not_in_use"|trans|raw,
'form': form,
'used': false,
'back': path('timesheet')
}) }}
{% endblock %}

View File

@@ -1,4 +1,4 @@
{% extends 'base.html.twig' %}
{% extends app.request.xmlHttpRequest ? 'form.html.twig' : 'base.html.twig' %}
{% import "macros/widgets.html.twig" as widgets %}
{% import "macros/datatables.html.twig" as tables %}
@@ -7,16 +7,19 @@
{% block main %}
{% set inUse = (stats.recordsTotal > 0) %}
{% set params = {
'%user%': '<strong>' ~ widgets.username(user) ~ '</strong>',
'%records%': '<strong>' ~ stats.recordsTotal ~ '</strong>',
'%duration%': '<strong>' ~ stats.durationTotal|duration ~ '</strong>'
} %}
{{ include('default/_form_delete.html.twig', {
{{ include(app.request.xmlHttpRequest ? 'default/_form_delete_modal.html.twig' : 'default/_form_delete.html.twig', {
'message': "admin_user.delete_confirm"|trans(params)|raw,
'form': form,
'back': path('admin_activity')
'used': inUse,
'back': path('admin_user')
}) }}
{% endblock %}

View File

@@ -58,7 +58,7 @@
{% set actionButtons = actionButtons|merge({'timesheet': path('admin_timesheet', {'user' : entry.id})}) %}
{% endif %}
{% if is_granted('delete', entry) %}
{% set actionButtons = actionButtons|merge({'trash': path('admin_user_delete', {'id': entry.id})}) %}
{% set actionButtons = actionButtons|merge({'trash': {'url': path('admin_user_delete', {'id': entry.id}), 'class': 'modal-ajax-form'}}) %}
{% endif %}
{{ widgets.button_group(actionButtons) }}
</td>

View File

@@ -9,13 +9,11 @@
namespace App\Tests\Controller;
use App\Entity\Activity;
use App\Entity\Timesheet;
use App\Entity\User;
use App\Tests\DataFixtures\ActivityFixtures;
use App\Tests\DataFixtures\ProjectFixtures;
use App\Tests\DataFixtures\TimesheetFixtures;
use Gedmo\Loggable\Entity\LogEntry;
/**
* @coversDefaultClass \App\Controller\ActivityController
@@ -122,7 +120,12 @@ class ActivityControllerTest extends ControllerBaseTest
$this->assertTrue($client->getResponse()->isSuccessful());
$this->request($client, '/admin/activity/1/delete');
$this->assertIsRedirect($client, $this->createUrl('/admin/activity/'));
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=form]')->form();
$this->assertStringEndsWith($this->createUrl('/admin/activity/1/delete'), $form->getUri());
$client->submit($form);
$client->followRedirect();
$this->assertHasFlashDeleteSuccess($client);
$this->assertHasNoEntriesWithFilter($client);

View File

@@ -9,12 +9,10 @@
namespace App\Tests\Controller;
use App\Entity\Customer;
use App\Entity\Timesheet;
use App\Entity\User;
use App\Tests\DataFixtures\CustomerFixtures;
use App\Tests\DataFixtures\TimesheetFixtures;
use Gedmo\Loggable\Entity\LogEntry;
/**
* @coversDefaultClass \App\Controller\CustomerController
@@ -92,9 +90,12 @@ class CustomerControllerTest extends ControllerBaseTest
$this->request($client, '/admin/customer/2/edit');
$this->assertTrue($client->getResponse()->isSuccessful());
$this->request($client, '/admin/customer/2/delete');
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/'));
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=form]')->form();
$this->assertStringEndsWith($this->createUrl('/admin/customer/2/delete'), $form->getUri());
$client->submit($form);
$client->followRedirect();
$this->assertHasDataTable($client);

View File

@@ -9,13 +9,11 @@
namespace App\Tests\Controller;
use App\Entity\Project;
use App\Entity\Timesheet;
use App\Entity\User;
use App\Tests\DataFixtures\CustomerFixtures;
use App\Tests\DataFixtures\ProjectFixtures;
use App\Tests\DataFixtures\TimesheetFixtures;
use Gedmo\Loggable\Entity\LogEntry;
/**
* @coversDefaultClass \App\Controller\ProjectController
@@ -116,9 +114,13 @@ class ProjectControllerTest extends ControllerBaseTest
$this->request($client, '/admin/project/2/edit');
$this->assertTrue($client->getResponse()->isSuccessful());
$this->request($client, '/admin/project/2/delete');
$this->assertIsRedirect($client, $this->createUrl('/admin/project/'));
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=form]')->form();
$this->assertStringEndsWith($this->createUrl('/admin/project/2/delete'), $form->getUri());
$client->submit($form);
$client->followRedirect();
$this->assertHasDataTable($client);
$this->assertHasFlashSuccess($client);

View File

@@ -157,10 +157,16 @@ class TimesheetControllerTest extends ControllerBaseTest
$this->assertTrue($client->getResponse()->isSuccessful());
$this->request($client, '/timesheet/1/delete');
$this->assertIsRedirect($client, $this->createUrl('/timesheet/page/1'));
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=form]')->form();
$this->assertStringEndsWith($this->createUrl('/timesheet/1/delete'), $form->getUri());
$client->submit($form);
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertHasFlashSuccess($client);
$this->assertHasFlashDeleteSuccess($client);
$this->assertHasDataTable($client);
$this->request($client, '/timesheet/1/edit');
$this->assertFalse($client->getResponse()->isSuccessful());

View File

@@ -14,7 +14,6 @@ use App\Entity\User;
use App\Form\Type\DateRangeType;
use App\Tests\Controller\ControllerBaseTest;
use App\Tests\DataFixtures\TimesheetFixtures;
use Gedmo\Loggable\Entity\LogEntry;
/**
* @coversDefaultClass \App\Controller\TimesheetTeamController
@@ -147,21 +146,6 @@ class TimesheetTeamControllerTest extends ControllerBaseTest
$this->assertNull($timesheet->getFixedRate());
}
public function testDeleteActionIsNotAllowedForTeamlead()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
$fixture = new TimesheetFixtures();
$fixture->setAmount(10);
$fixture->setUser($this->getUserByRole($em, User::ROLE_USER));
$fixture->setStartDate('2017-05-01');
$this->importFixture($em, $fixture);
$this->request($client, '/team/timesheet/1/delete');
$this->assertFalse($client->getResponse()->isSuccessful());
}
public function testDeleteAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
@@ -177,10 +161,16 @@ class TimesheetTeamControllerTest extends ControllerBaseTest
$this->assertTrue($client->getResponse()->isSuccessful());
$this->request($client, '/team/timesheet/1/delete');
$this->assertIsRedirect($client, $this->createUrl('/team/timesheet/page/1'));
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=form]')->form();
$this->assertStringEndsWith($this->createUrl('/team/timesheet/1/delete'), $form->getUri());
$client->submit($form);
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertHasFlashSuccess($client);
$this->assertHasFlashDeleteSuccess($client);
$this->assertHasDataTable($client);
$this->request($client, '/team/timesheet/1/edit');
$this->assertFalse($client->getResponse()->isSuccessful());

View File

@@ -9,7 +9,9 @@
namespace App\Tests\Controller;
use App\Entity\Timesheet;
use App\Entity\User;
use App\Tests\DataFixtures\TimesheetFixtures;
/**
* @coversDefaultClass \App\Controller\UserController
@@ -86,6 +88,60 @@ class UserControllerTest extends ControllerBaseTest
$this->assertEquals(1, $form->get('user_create[create_more]')->getValue());
}
public function testDeleteAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
$this->request($client, '/admin/user/4/delete');
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=form]')->form();
$this->assertStringEndsWith($this->createUrl('/admin/user/4/delete'), $form->getUri());
$client->submit($form);
$client->followRedirect();
$this->assertHasDataTable($client);
$this->assertHasFlashSuccess($client);
$this->request($client, '/admin/user/4/edit');
$this->assertFalse($client->getResponse()->isSuccessful());
}
public function testDeleteActionWithTimesheetEntries()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
$user = $this->getUserByRole($em, User::ROLE_USER);
$fixture = new TimesheetFixtures();
$fixture->setUser($user);
$fixture->setAmount(10);
$this->importFixture($em, $fixture);
$timesheets = $em->getRepository(Timesheet::class)->findAll();
$this->assertEquals(10, count($timesheets));
$this->request($client, '/admin/user/' . $user->getId() . '/delete');
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=form]')->form();
$this->assertStringEndsWith($this->createUrl('/admin/user/' . $user->getId() . '/delete'), $form->getUri());
$client->submit($form);
$this->assertIsRedirect($client, $this->createUrl('/admin/user/'));
$client->followRedirect();
$this->assertHasFlashDeleteSuccess($client);
// SQLIte does not necessarly support onCascade delete, so these timesheet will stay after deletion
// $em->clear();
// $timesheets = $em->getRepository(Timesheet::class)->findAll();
// $this->assertEquals(0, count($timesheets));
$this->request($client, '/admin/user/' . $user->getId() . '/edit');
$this->assertFalse($client->getResponse()->isSuccessful());
}
/**
* @dataProvider getValidationTestData
*/

View File

@@ -39,9 +39,11 @@
</trans-unit>
<trans-unit id="confirm.delete_message">
<source>confirm.delete_message</source>
<target>
Sie müssen das Löschen erneut bestätigen, da verknüpfte Objekte existieren welche ebenfalls mit gelöscht werden.
</target>
<target>Sie müssen das Löschen erneut bestätigen, da verknüpfte Objekte existieren welche ebenfalls mit gelöscht werden.</target>
</trans-unit>
<trans-unit id="delete.not_in_use">
<source>delete.not_in_use</source>
<target>Dieses Element kann sicher gelöscht werden.</target>
</trans-unit>
<!--

View File

@@ -39,9 +39,11 @@
</trans-unit>
<trans-unit id="confirm.delete_message">
<source>confirm.delete_message</source>
<target>
You have to confirm the deletion, as there are linked objects which will be deleted as well.
</target>
<target>You have to confirm the deletion, as there are linked objects which will be deleted as well.</target>
</trans-unit>
<trans-unit id="delete.not_in_use">
<source>delete.not_in_use</source>
<target>This item can be safely deleted.</target>
</trans-unit>
<!--

View File

@@ -9,6 +9,10 @@
لمساعدتي في تحسين Kimai, الرجاء إرسال رسالتك على موقع الويب المرتبط. سواء كان لديك أسئلة أو للتبليغ عن خطأ أو عطل أو أفكار للتحسينات ، فإن تعليقاتك ذات قيمة!
]]></target>
</trans-unit>
<trans-unit id="home.help">
<source>home.help</source>
<target>مساعدة</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -19,6 +19,10 @@
<source>home.website</source>
<target>Homepage</target>
</trans-unit>
<trans-unit id="home.help">
<source>home.help</source>
<target>Hilfe</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -19,6 +19,10 @@
<source>home.website</source>
<target>Homepage</target>
</trans-unit>
<trans-unit id="home.help">
<source>home.help</source>
<target>Help</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -11,6 +11,10 @@
Para ayudar a mejorar Kimai, por favor enviar sus comentarios al sitio. Sus comentarios, ideas para mejorar o reportes de errores son valiosos y agradezco el tiempo para enviárnoslos!
]]></target>
</trans-unit>
<trans-unit id="home.help">
<source>home.help</source>
<target>Ayuda</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -11,6 +11,10 @@
Pour m'aider à améliorer Kimai, merci de poster votre message sur le site lié. Que vous ayez des questions, des messages ou des idées d'améliorations, vos retours sont précieux !
]]></target>
</trans-unit>
<trans-unit id="home.help">
<source>home.help</source>
<target>Aide</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -21,6 +21,10 @@
<source>home.website</source>
<target>Weboldal</target>
</trans-unit>
<trans-unit id="home.help">
<source>home.help</source>
<target>Súgó</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -11,6 +11,10 @@
To help me improve Kimai, please send your message on the linked website. Whether you have questions, error messages or ideas for enhancements, your feedback is valuable!
]]></target>
</trans-unit>
<trans-unit id="home.help">
<source>home.help</source>
<target>Aiuto</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -19,6 +19,10 @@
<source>home.website</source>
<target>Homepage</target>
</trans-unit>
<trans-unit id="home.help">
<source>home.help</source>
<target>Ajuda</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -11,6 +11,10 @@
Для помощи в усовершенствовании Kimai, пожалуйства, отправляйте свои сообщения на страницу под ссылкой. Приветствуются любые вопросы, идеи по разработке, в частности на тему дополнительных функций, а также сообщения об ошибках. Нам очень важна Ваша обратная связь!
]]></target>
</trans-unit>
<trans-unit id="home.help">
<source>home.help</source>
<target>Помощь</target>
</trans-unit>
</body>
</file>
</xliff>