diff --git a/app/Exports/FormSubmissionExport.php b/app/Exports/FormSubmissionExport.php index e8c5a8c..9e60e95 100644 --- a/app/Exports/FormSubmissionExport.php +++ b/app/Exports/FormSubmissionExport.php @@ -16,7 +16,7 @@ class FormSubmissionExport implements FromArray, WithHeadingRow $contentRow = []; foreach ($submissionData as $i => $row) { if($i==0){ - $headingRow[] = array_keys($row); + $headingRow[] = $this->cleanColumnNames(array_keys($row)); } $contentRow[] = array_values($row); } @@ -27,6 +27,13 @@ class FormSubmissionExport implements FromArray, WithHeadingRow ]; } + private function cleanColumnNames(array $columnNames): array + { + return collect($columnNames)->map(function ($columnName) { + return preg_replace('/\s\(.*\)/', '', $columnName); + })->toArray(); + } + public function array(): array { return $this->submissionData; diff --git a/app/Http/Controllers/Forms/FormSubmissionController.php b/app/Http/Controllers/Forms/FormSubmissionController.php index 1c4e007..8b44624 100644 --- a/app/Http/Controllers/Forms/FormSubmissionController.php +++ b/app/Http/Controllers/Forms/FormSubmissionController.php @@ -14,6 +14,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; use Maatwebsite\Excel\Facades\Excel; +use Vinkla\Hashids\Facades\Hashids; class FormSubmissionController extends Controller { @@ -25,29 +26,29 @@ class FormSubmissionController extends Controller public function submissions(string $id) { - $form = Form::findOrFail((int) $id); + $form = Form::findOrFail((int)$id); $this->authorize('view', $form); return FormSubmissionResource::collection($form->submissions()->paginate(100)); } - public function update(AnswerFormRequest $request, $id, $submissionId) + public function update(AnswerFormRequest $request, $id, $submissionId) { - $form = $request->form; + $form = $request->form; $this->authorize('update', $form); $job = new StoreFormSubmissionJob($request->form, $request->validated()); $job->setSubmissionId($submissionId)->handle(); - $data = new FormSubmissionResource(FormSubmission::findOrFail($submissionId)); + $data = new FormSubmissionResource(FormSubmission::findOrFail($submissionId)); return $this->success([ 'message' => 'Record successfully updated.', - 'data' => $data + 'data' => $data ]); } public function export(string $id) { - $form = Form::findOrFail((int) $id); + $form = Form::findOrFail((int)$id); $this->authorize('view', $form); $allRows = []; @@ -56,23 +57,26 @@ class FormSubmissionController extends Controller ->outputStringsOnly() ->setEmptyForNoValue() ->showRemovedFields() + ->showHiddenFields() ->useSignedUrlForFiles(); - $tmp = $formatter->getCleanKeyValue(); - $tmp['Create Date'] = date("Y-m-d H:i", strtotime($row['created_at'])); - $allRows[] = $tmp; + $allRows[] = [ + 'id' => Hashids::encode($row['id']), + 'created_at' => date("Y-m-d H:i", strtotime($row['created_at'])), + ...$formatter->getCleanKeyValue() + ]; } $csvExport = (new FormSubmissionExport($allRows)); return Excel::download( $csvExport, - $form->slug.'-submission-data.csv', + $form->slug . '-submission-data.csv', \Maatwebsite\Excel\Excel::CSV ); } public function submissionFile($id, $fileName) { - $fileName = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $id).'/' - .urldecode($fileName); + $fileName = Str::of(PublicFormController::FILE_UPLOAD_PATH)->replace('?', $id) . '/' + . urldecode($fileName); if (!Storage::exists($fileName)) { return $this->error([ @@ -85,7 +89,7 @@ class FormSubmissionController extends Controller } return redirect( - Storage::temporaryUrl($fileName, now()->addMinute()) + Storage::temporaryUrl($fileName, now()->addMinute()) ); } } diff --git a/app/Service/Forms/FormSubmissionFormatter.php b/app/Service/Forms/FormSubmissionFormatter.php index d46fe50..8fbab0d 100644 --- a/app/Service/Forms/FormSubmissionFormatter.php +++ b/app/Service/Forms/FormSubmissionFormatter.php @@ -85,15 +85,35 @@ class FormSubmissionFormatter public function getCleanKeyValue() { $data = $this->formData; - $fields = ($this->showRemovedFields) ? array_merge($this->form->properties, $this->form->removed_properties) : $this->form->properties; + + $fields = collect($this->form->properties); + $removeFields = collect($this->form->removed_properties)->map(function ($field) { + return [ + ...$field, + 'removed' => true + ]; + }); + if ($this->showRemovedFields) { + $fields = $fields->merge($removeFields); + } + $fields = $fields->filter(function ($field) { + return !in_array($field['type'],['nf-text', 'nf-code', 'nf-page-break', 'nf-divider', 'nf-image']); + })->values(); $returnArray = []; - foreach ($fields as &$field) { - $isRemoved = in_array($field['id'], array_column($this->form->removed_properties, 'id')) ?? false; - if($isRemoved){ + foreach ($fields as $field) { + + if (in_array($field['id'],['nf-text', 'nf-code', 'nf-page-break', 'nf-divider', 'nf-image'])) { + continue; + } + + if($field['removed'] ?? false) { $field['name'] = $field['name']." (deleted)"; } + // Add ID to avoid name clashes + $field['name'] = $field['name'].' ('.\Str::of($field['id']).')'; + // If not present skip if (!isset($data[$field['id']])) { if ($this->setEmptyForNoValue) { diff --git a/client/components/open/forms/components/FormSubmissions.vue b/client/components/open/forms/components/FormSubmissions.vue index 9459b8b..b104a30 100644 --- a/client/components/open/forms/components/FormSubmissions.vue +++ b/client/components/open/forms/components/FormSubmissions.vue @@ -71,9 +71,10 @@ >Display columns

- Export as CSV +

@@ -136,6 +137,7 @@ export default { properties: [], removed_properties: [], displayColumns: {}, + exportLoading: false, searchForm: useForm({ search: '' }), @@ -184,6 +186,9 @@ export default { watch: { 'form.id'() { this.onFormChange() + }, + 'searchForm.search'() { + this.dataChanged() } }, mounted() { @@ -271,6 +276,10 @@ export default { this.dataChanged() }, downloadAsCsv() { + if (this.exportLoading) { + return + } + this.exportLoading = true opnFetch(this.exportUrl, {responseType: "blob"}) .then(blob => { const filename = `${this.form.slug}-${Date.now()}-submissions.csv` @@ -284,6 +293,8 @@ export default { window.URL.revokeObjectURL(url) }).catch((error) => { console.error(error) + }).finally(() => { + this.exportLoading = false }) } }