diff --git a/appinfo/routes.php b/appinfo/routes.php index ad1e162..e051902 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -54,7 +54,10 @@ return [ ['name' => 'api#updateOption', 'url' => '/api/v1/option/update', 'verb' => 'POST'], ['name' => 'api#deleteOption', 'url' => '/api/v1/option/{id}', 'verb' => 'DELETE'], + // Submissions ['name' => 'api#getSubmissions', 'url' => '/api/v1/submissions/{hash}', 'verb' => 'GET'], + ['name' => 'api#deleteAllSubmissions', 'url' => '/api/v1/submissions/{formId}', 'verb' => 'DELETE'], + ['name' => 'api#insertSubmission', 'url' => '/api/v1/submission/insert', 'verb' => 'POST'], ['name' => 'api#deleteSubmission', 'url' => '/api/v1/submission/{id}', 'verb' => 'DELETE'], diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php index 85f3190..fdb3d73 100644 --- a/lib/Controller/ApiController.php +++ b/lib/Controller/ApiController.php @@ -741,4 +741,30 @@ class ApiController extends Controller { return new Http\JSONResponse($id); } + + /** + * @NoAdminRequired + */ + public function deleteAllSubmissions(int $formId): Http\JSONResponse { + $this->logger->debug('Delete all submissions to form: {formId}', [ + 'formId' => $formId, + ]); + + try { + $form = $this->formMapper->findById($formId); + } catch (IMapperException $e) { + $this->logger->debug('Could not find form'); + return new Http\JSONResponse([], Http::STATUS_BAD_REQUEST); + } + + if ($form->getOwnerId() !== $this->userId) { + $this->logger->debug('This form is not owned by the current user'); + return new Http\JSONResponse([], Http::STATUS_FORBIDDEN); + } + + // Delete all submissions (incl. Answers) + $this->submissionMapper->deleteByForm($formId); + + return new Http\JSONResponse($id); + } } diff --git a/src/views/Results.vue b/src/views/Results.vue index 790acc5..9028c6d 100644 --- a/src/views/Results.vue +++ b/src/views/Results.vue @@ -39,10 +39,14 @@

{{ t('forms', 'Responses for {title}', { title: form.title }) }}

- + + + {{ t('forms', 'Export to CSV') }} + + + {{ t('forms', 'Delete all Submissions') }} + +
@@ -71,6 +75,8 @@ import { generateUrl } from '@nextcloud/router' import { Parser } from 'json2csv' import { showError } from '@nextcloud/dialogs' +import Actions from '@nextcloud/vue/dist/Components/Actions' +import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import AppContent from '@nextcloud/vue/dist/Components/AppContent' import axios from '@nextcloud/axios' import moment from '@nextcloud/moment' @@ -84,6 +90,8 @@ export default { name: 'Results', components: { + Actions, + ActionButton, AppContent, EmptyContent, Submission, @@ -154,6 +162,23 @@ export default { } }, + async deleteAllSubmissions() { + if (!confirm(t('forms', 'Are you sure you want to delete all submissions from this form?'))) { + return + } + + this.loadingResults = true + try { + await axios.delete(generateUrl('/apps/forms/api/v1/submissions/{formId}', { formId: this.form.id })) + this.submissions = [] + } catch (error) { + console.error(error) + showError(t('forms', 'There was an error while removing the submissions')) + } finally { + this.loadingResults = false + } + }, + download() { this.loadingResults = true