Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e52443830 | ||
|
|
a46d008cc6 | ||
|
|
3267c3bff8 | ||
|
|
2f68d49f4b | ||
|
|
6be0993c98 |
@@ -1,3 +1,10 @@
|
||||
# Version 4.4.0
|
||||
* Added possibility to create one shot job from scheduled job
|
||||
|
||||
# Version 4.3.0
|
||||
|
||||
* Replaced date field with date picker
|
||||
|
||||
# Version 4.2.0
|
||||
|
||||
* Added error count columns to job tables
|
||||
|
||||
@@ -8,6 +8,7 @@ use CodeRhapsodie\DataflowBundle\Entity\Job;
|
||||
use CodeRhapsodie\DataflowBundle\Entity\ScheduledDataflow;
|
||||
use CodeRhapsodie\EzDataflowBundle\Form\CreateOneshotType;
|
||||
use CodeRhapsodie\EzDataflowBundle\Form\CreateScheduledType;
|
||||
use CodeRhapsodie\EzDataflowBundle\Form\UpdateScheduledType;
|
||||
use CodeRhapsodie\EzDataflowBundle\Gateway\ExceptionJSONDecoderAdapter;
|
||||
use CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway;
|
||||
use CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway;
|
||||
@@ -55,10 +56,12 @@ class DashboardController extends Controller
|
||||
$form = $this->createForm(CreateScheduledType::class, $newWorkflow, [
|
||||
'action' => $this->generateUrl('coderhapsodie.ezdataflow.workflow.create'),
|
||||
]);
|
||||
$updateForm = $this->createForm(UpdateScheduledType::class);
|
||||
|
||||
return $this->render('@ibexadesign/ezdataflow/Dashboard/repeating.html.twig', [
|
||||
'pager' => $this->getPager($this->scheduledDataflowGateway->getListQueryForAdmin(), $request),
|
||||
'form' => $form->createView(),
|
||||
'update_form' => $updateForm->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,12 +7,14 @@ namespace CodeRhapsodie\EzDataflowBundle\Controller;
|
||||
use CodeRhapsodie\DataflowBundle\Entity\Job;
|
||||
use CodeRhapsodie\EzDataflowBundle\Form\CreateOneshotType;
|
||||
use CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway;
|
||||
use CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway;
|
||||
use Ibexa\Contracts\AdminUi\Controller\Controller;
|
||||
use Ibexa\Contracts\AdminUi\Notification\NotificationHandlerInterface;
|
||||
use Ibexa\Core\MVC\Symfony\Security\Authorization\Attribute;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
@@ -28,15 +30,19 @@ class JobController extends Controller
|
||||
private $notificationHandler;
|
||||
/** @var \Symfony\Contracts\Translation\TranslatorInterface */
|
||||
private $translator;
|
||||
/** @var \CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway */
|
||||
private $scheduledDataflowGateway;
|
||||
|
||||
public function __construct(
|
||||
JobGateway $jobGateway,
|
||||
NotificationHandlerInterface $notificationHandler,
|
||||
TranslatorInterface $translator
|
||||
TranslatorInterface $translator,
|
||||
ScheduledDataflowGateway $scheduledDataflowGateway
|
||||
) {
|
||||
$this->jobGateway = $jobGateway;
|
||||
$this->notificationHandler = $notificationHandler;
|
||||
$this->translator = $translator;
|
||||
$this->scheduledDataflowGateway = $scheduledDataflowGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,4 +110,37 @@ class JobController extends Controller
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/run-oneshot/{id}", name="coderhapsodie.ezdataflow.job.run-oneshot", methods={"GET"})
|
||||
*/
|
||||
public function runOneShot(int $id): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
|
||||
|
||||
$scheduledDataflow = $this->scheduledDataflowGateway->find($id);
|
||||
|
||||
if ($scheduledDataflow === null) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
$newOneshotJob = new Job();
|
||||
$newOneshotJob->setOptions($scheduledDataflow->getOptions());
|
||||
$newOneshotJob->setLabel("Manual " . $scheduledDataflow->getLabel());
|
||||
$newOneshotJob->setScheduledDataflowId($scheduledDataflow->getId());
|
||||
$newOneshotJob->setRequestedDate((new \DateTime())->add(new \DateInterval('PT1H')));
|
||||
$newOneshotJob->setDataflowType($scheduledDataflow->getDataflowType());
|
||||
|
||||
$form = $this->createForm(CreateOneshotType::class, $newOneshotJob, [
|
||||
'action' => $this->generateUrl('coderhapsodie.ezdataflow.job.create'),
|
||||
]);
|
||||
|
||||
return new JsonResponse([
|
||||
'form' => $this->renderView('@ibexadesign/ezdataflow/parts/form_modal.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'id' => 'modal-new-oneshot',
|
||||
'mode' => 'oneshot',
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ class CreateOneshotType extends AbstractType
|
||||
])
|
||||
->add('requestedDate', UserTimezoneAwareDateTimeType::class, [
|
||||
'label' => 'coderhapsodie.dataflow.requestedDate',
|
||||
'years' => range(date('Y'), date('Y') + 5),
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ class CreateScheduledType extends AbstractType
|
||||
'label' => 'coderhapsodie.dataflow.frequency',
|
||||
])
|
||||
->add('next', UserTimezoneAwareDateTimeType::class, [
|
||||
'years' => range(date('Y'), date('Y') + 5),
|
||||
'label' => 'coderhapsodie.dataflow.create.next',
|
||||
])
|
||||
->add('enabled', CheckboxType::class, [
|
||||
|
||||
@@ -32,7 +32,6 @@ class UpdateScheduledType extends AbstractType
|
||||
'label' => 'coderhapsodie.dataflow.frequency',
|
||||
])
|
||||
->add('next', UserTimezoneAwareDateTimeType::class, [
|
||||
'years' => range(date('Y'), date('Y') + 5),
|
||||
'label' => 'coderhapsodie.dataflow.update.next',
|
||||
])
|
||||
;
|
||||
|
||||
@@ -4,9 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Form;
|
||||
|
||||
use Ibexa\AdminUi\Form\Type\DateTimePickerType;
|
||||
use Ibexa\Contracts\Core\Repository\UserPreferenceService;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class UserTimezoneAwareDateTimeType extends AbstractType
|
||||
@@ -21,7 +21,7 @@ class UserTimezoneAwareDateTimeType extends AbstractType
|
||||
|
||||
public function getParent()
|
||||
{
|
||||
return DateTimeType::class;
|
||||
return DateTimePickerType::class;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
|
||||
@@ -38,6 +38,7 @@ services:
|
||||
$jobGateway: '@CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway'
|
||||
$notificationHandler: '@Ibexa\Contracts\AdminUi\Notification\NotificationHandlerInterface'
|
||||
$translator: '@translator'
|
||||
$scheduledDataflowGateway: '@CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway'
|
||||
calls:
|
||||
- [ 'setContainer', [ '@service_container' ] ]
|
||||
- [ 'performAccessCheck', [ ] ]
|
||||
|
||||
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 273 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 60 KiB |
@@ -16,6 +16,7 @@ coderhapsodie.ezdataflow.workflow.list.history: History
|
||||
coderhapsodie.ezdataflow.workflow.list.edit: Edit
|
||||
coderhapsodie.ezdataflow.workflow.list.disable: Disable
|
||||
coderhapsodie.ezdataflow.workflow.list.enable: Enable
|
||||
coderhapsodie.ezdataflow.workflow.list.runonce: Run now
|
||||
coderhapsodie.ezdataflow.history.title: History
|
||||
coderhapsodie.ezdataflow.history.list.title: 'Executions list'
|
||||
coderhapsodie.ezdataflow.history.list.name: Name
|
||||
|
||||
@@ -16,6 +16,7 @@ coderhapsodie.ezdataflow.workflow.list.history: Historique
|
||||
coderhapsodie.ezdataflow.workflow.list.edit: Éditer
|
||||
coderhapsodie.ezdataflow.workflow.list.disable: Désactiver
|
||||
coderhapsodie.ezdataflow.workflow.list.enable: Activer
|
||||
coderhapsodie.ezdataflow.workflow.list.runonce: Lancer maintenant
|
||||
coderhapsodie.ezdataflow.history.title: Historique
|
||||
coderhapsodie.ezdataflow.history.list.title: 'Liste des exécutions'
|
||||
coderhapsodie.ezdataflow.history.list.name: Nom
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
{%- block content -%}
|
||||
{% set actions %}
|
||||
<button
|
||||
type="button"
|
||||
class="btn ibexa-btn ibexa-btn--tertiary ibexa-btn--small"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#modal-new-oneshot"
|
||||
id="create-oneshot-button"
|
||||
type="button"
|
||||
class="btn ibexa-btn ibexa-btn--tertiary ibexa-btn--small"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#modal-new-oneshot"
|
||||
>
|
||||
<svg class="ibexa-icon ibexa-icon--small ibexa-icon--create">
|
||||
<use xlink:href="{{ ibexa_icon_path('create') }}"></use>
|
||||
@@ -53,6 +54,16 @@
|
||||
})
|
||||
;
|
||||
});
|
||||
const createButton = document.getElementById('create-oneshot-button')
|
||||
|
||||
if (createButton) {
|
||||
createButton.addEventListener('click', () => {
|
||||
const oneShotModal = document.getElementById('modal-new-oneshot');
|
||||
oneShotModal.querySelector('#create_oneshot_label').value = '';
|
||||
oneShotModal.querySelector('#create_oneshot_options').value = '';
|
||||
oneShotModal.querySelector('.flatpickr.flatpickr-input').parentNode.parentNode.ibexaInstance.flatpickrInstance.setDate(new Date(), true);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{%- endblock -%}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{%- block content -%}
|
||||
{% form_theme update_form '@ibexadesign/ezdataflow/form_theme.html.twig' %}
|
||||
|
||||
{{ include('@ibexadesign/ezdataflow/parts/tab/schedule_list.html.twig', {
|
||||
identifier: 'ezdataflow_schedule_results',
|
||||
@@ -15,10 +16,12 @@
|
||||
title: 'coderhapsodie.ezdataflow.workflow.repeating.edit.title'|trans,
|
||||
} %}
|
||||
{% block body_content %}
|
||||
<form action="" method="post">
|
||||
<div class="form-fields"></div>
|
||||
{{ form_start(update_form) }}
|
||||
<div class="form-fields">
|
||||
{{ form_widget(update_form) }}
|
||||
</div>
|
||||
<button id="modal-edit-submit" type="submit" hidden />
|
||||
</form>
|
||||
{{ form_end(update_form) }}
|
||||
{% endblock %}
|
||||
{% block footer_content %}
|
||||
<button type="button" class="btn ibexa-btn ibexa-btn--primary ibexa-btn--trigger" data-click="#modal-edit-submit">
|
||||
@@ -52,50 +55,6 @@
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// $('#ez-modal--edit-scheduled').modal({keyboard: true, show: false});
|
||||
// $('.modal-edit').each(function (index, elem) {
|
||||
// $(elem).click(function (e) {
|
||||
// e.preventDefault();
|
||||
// $('#schedule_edit').html('');
|
||||
// $('#ez-modal--edit-scheduled').modal('show');
|
||||
// $.ajax(elem.href, {
|
||||
// success: function (result) {
|
||||
// if (result.redirect) {
|
||||
// if (window.location.href === result.redirect) {
|
||||
// window.location.reload();
|
||||
// }
|
||||
// window.location = result.redirect;
|
||||
// window.location.reload();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// $('#schedule_edit').html(result.form);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// $('#ez-modal--edit-scheduled').on('submit', 'form', function (e) {
|
||||
// e.preventDefault();
|
||||
// url = $(this).attr('action');
|
||||
// data = new FormData(this);
|
||||
// $.ajax({
|
||||
// 'type': 'POST',
|
||||
// 'url': url,
|
||||
// 'data': data,
|
||||
// processData: false,
|
||||
// contentType: false,
|
||||
// success: function (result) {
|
||||
// if (result.redirect) {
|
||||
// window.location = result.redirect;
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// $('#schedule_edit').html(result.form);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
const bindFormSubmit = (modalId) => {
|
||||
document.querySelector('#'+modalId+' form').addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
@@ -134,7 +93,13 @@
|
||||
const node = document.createElement('div');
|
||||
node.innerHTML = result.form;
|
||||
editModal.querySelector('form').action = link.href;
|
||||
editModal.querySelector('.form-fields').innerHTML = node.querySelector('.form-fields').innerHTML;
|
||||
editModal.querySelector('#update_scheduled_label').value = node.querySelector('#update_scheduled_label').value;
|
||||
editModal.querySelector('#update_scheduled_options').value = node.querySelector('#update_scheduled_options').value;
|
||||
editModal.querySelector('#update_scheduled_frequency').value = node.querySelector('#update_scheduled_frequency').value;
|
||||
editModal.querySelector('#update_scheduled_next').parentNode.parentNode.ibexaInstance.flatpickrInstance.setDate(
|
||||
new Date(node.querySelector('#update_scheduled_next').value * 1000),
|
||||
true
|
||||
);
|
||||
})
|
||||
;
|
||||
|
||||
|
||||
@@ -40,6 +40,15 @@
|
||||
<use xlink:href="{{ ibexa_icon_path('edit') }}"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<button
|
||||
class="btn ibexa-btn ibexa-btn--ghost run-oneshot ibexa-btn--no-text"
|
||||
data-url="{{ path('coderhapsodie.ezdataflow.job.run-oneshot', {id: item.id}) }}"
|
||||
title="{{ 'coderhapsodie.ezdataflow.workflow.list.runonce'|trans }}"
|
||||
>
|
||||
<svg class="ibexa-icon ibexa-icon--small ibexa-icon--create">
|
||||
<use xlink:href="{{ ibexa_icon_path('create') }}"></use>
|
||||
</svg>
|
||||
</button>
|
||||
{% if item.enabled %}
|
||||
<a href="{{ path('coderhapsodie.ezdataflow.workflow.disable', {id: item.id}) }}"
|
||||
class="btn ibexa-btn ibexa-btn--ghost ibexa-btn--no-text"
|
||||
@@ -125,3 +134,27 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.querySelectorAll(".run-oneshot").forEach((el) => {
|
||||
el.addEventListener('click', () => {
|
||||
const oneShotModal = document.getElementById('modal-new-oneshot');
|
||||
|
||||
fetch(el.getAttribute('data-url'))
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
const node = document.createElement('div');
|
||||
node.innerHTML = result.form;
|
||||
oneShotModal.querySelector('#create_oneshot_label').value = node.querySelector('#create_oneshot_label').value;
|
||||
oneShotModal.querySelector('#create_oneshot_options').value = node.querySelector('#create_oneshot_options').value;
|
||||
oneShotModal.querySelector('.ibexa-dropdown').ibexaInstance.selectOption(node.querySelector('#create_oneshot_dataflowType').value)
|
||||
oneShotModal.querySelector('.flatpickr.flatpickr-input').parentNode.parentNode.ibexaInstance.flatpickrInstance.setDate(new Date(), true);
|
||||
})
|
||||
.then(() => {
|
||||
bootstrap.Tab.getOrCreateInstance(document.querySelector('#ibexa-tab-label-coderhapsodie-ezdataflow-code-rhapsodie-ezdataflow-oneshot')).show()
|
||||
bootstrap.Modal.getOrCreateInstance(oneShotModal).show()
|
||||
})
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||