diff --git a/appinfo/routes.php b/appinfo/routes.php index e8ee2bf2..26fb4da9 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -20,6 +20,7 @@ ['name' => 'synchronizations#contracts', 'url' => '/api/synchronizations-contracts/{id}', 'verb' => 'GET'], ['name' => 'synchronizations#logs', 'url' => '/api/synchronizations-logs/{id}', 'verb' => 'GET'], ['name' => 'synchronizations#test', 'url' => '/api/synchronizations-test/{id}', 'verb' => 'POST'], + ['name' => 'synchronizations#run', 'url' => '/api/synchronizations-run/{id}', 'verb' => 'POST'], // Mapping endpoints ['name' => 'mappings#test', 'url' => '/api/mappings/test', 'verb' => 'POST'], ['name' => 'mappings#saveObject', 'url' => '/api/mappings/objects', 'verb' => 'POST'], diff --git a/lib/Controller/SynchronizationsController.php b/lib/Controller/SynchronizationsController.php index 6ba49a31..89c1f348 100644 --- a/lib/Controller/SynchronizationsController.php +++ b/lib/Controller/SynchronizationsController.php @@ -278,4 +278,51 @@ public function test(int $id): JSONResponse ); } } + + /** + * Run a synchronization + * + * @NoAdminRequired + * @NoCSRFRequired + * + * Endpoint: /api/synchronizations-run/{id} + * + * @param int $id The ID of the synchronization to test + * @return JSONResponse A JSON response containing the run results + * @throws GuzzleException + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function run(int $id): JSONResponse + { + try { + $synchronization = $this->synchronizationMapper->find(id: $id); + } catch (DoesNotExistException $exception) { + return new JSONResponse(data: ['error' => 'Not Found'], statusCode: 404); + } + + // Try to synchronize + try { + $logAndContractArray = $this->synchronizationService->synchronize( + synchronization: $synchronization, + isTest: false + ); + + // Return the result as a JSON response + return new JSONResponse(data: $logAndContractArray, statusCode: 200); + } catch (Exception $e) { + // Check if getHeaders method exists and use it if available + $headers = method_exists($e, 'getHeaders') ? $e->getHeaders() : []; + + // If synchronization fails, return an error response + return new JSONResponse( + data: [ + 'error' => 'Synchronization error', + 'message' => $e->getMessage() + ], + statusCode: $e->getCode() ?? 400, + headers: $headers + ); + } + } } diff --git a/src/modals/Modals.vue b/src/modals/Modals.vue index c0287073..38dcb8d1 100644 --- a/src/modals/Modals.vue +++ b/src/modals/Modals.vue @@ -28,6 +28,7 @@ import { navigationStore } from '../store/store.js' + @@ -64,6 +65,7 @@ import TestMapping from './MappingTest/TestMapping.vue' import EditSynchronization from './Synchronization/EditSynchronization.vue' import DeleteSynchronization from './Synchronization/DeleteSynchronization.vue' import TestSynchronization from './Synchronization/TestSynchronization.vue' +import RunSynchronization from './Synchronization/RunSynchronization.vue' import EditJobArgument from './JobArgument/EditJobArgument.vue' import DeleteJobArgument from './JobArgument/DeleteJobArgument.vue' import EditSourceConfiguration from './SourceConfiguration/EditSourceConfiguration.vue' @@ -106,6 +108,7 @@ export default { DeleteSynchronization, EditSynchronization, TestSynchronization, + RunSynchronization, EditJobArgument, DeleteJobArgument, EditSourceConfiguration, diff --git a/src/modals/Synchronization/RunSynchronization.vue b/src/modals/Synchronization/RunSynchronization.vue new file mode 100644 index 00000000..81f728b5 --- /dev/null +++ b/src/modals/Synchronization/RunSynchronization.vue @@ -0,0 +1,245 @@ + + + + + + + + diff --git a/src/store/modules/synchronization.js b/src/store/modules/synchronization.js index 797e7258..afa03f09 100644 --- a/src/store/modules/synchronization.js +++ b/src/store/modules/synchronization.js @@ -7,6 +7,7 @@ export const useSynchronizationStore = defineStore('synchronization', { synchronizationList: [], synchronizationContracts: [], synchronizationTest: null, + synchronizationRun: null, synchronizationLogs: [], synchronizationSourceConfigKey: null, synchronizationTargetConfigKey: null, @@ -209,6 +210,31 @@ export const useSynchronizationStore = defineStore('synchronization', { console.info('Synchronization tested') this.refreshSynchronizationLogs() + return { response, data } + }, + // Test a synchronization + async runSynchronization(id) { + if (!id) { + throw new Error('No synchronization item to run') + } + + console.info('Testing synchronization...') + + const endpoint = `/index.php/apps/openconnector/api/synchronizations-run/${id}` + + const response = await fetch(endpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }) + + const data = await response.json() + this.synchronizationRun = data + + console.info('Synchronization run') + this.refreshSynchronizationLogs() + return { response, data } }, }, diff --git a/src/views/Synchronization/SynchronizationDetails.vue b/src/views/Synchronization/SynchronizationDetails.vue index edb37a99..e8f6c8e4 100644 --- a/src/views/Synchronization/SynchronizationDetails.vue +++ b/src/views/Synchronization/SynchronizationDetails.vue @@ -39,6 +39,12 @@ import { synchronizationStore, navigationStore, logStore } from '../../store/sto Test + + + Run +