Add: Delete participant
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
f05a919b9c
commit
8e3054da49
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form\Actions;
|
||||||
|
|
||||||
|
use App\Form\Models\Participant;
|
||||||
|
use App\Lib\JobMiddleware\JobChannels;
|
||||||
|
use App\Lib\JobMiddleware\WithJobState;
|
||||||
|
use App\Lib\Queue\TracksJob;
|
||||||
|
use Lorisleiva\Actions\Concerns\AsAction;
|
||||||
|
|
||||||
|
class ParticipantDestroyAction
|
||||||
|
{
|
||||||
|
use AsAction;
|
||||||
|
use TracksJob;
|
||||||
|
|
||||||
|
public function handle(int $participantId): void
|
||||||
|
{
|
||||||
|
Participant::findOrFail($participantId)->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function asController(Participant $participant): void
|
||||||
|
{
|
||||||
|
$this->startJob($participant->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $parameters
|
||||||
|
*/
|
||||||
|
public function jobState(WithJobState $jobState, ...$parameters): WithJobState
|
||||||
|
{
|
||||||
|
return $jobState
|
||||||
|
->after('Teilnehmer gelöscht.')
|
||||||
|
->failed('Löschen von Teilnehmer fehlgeschlagen.')
|
||||||
|
->shouldReload(JobChannels::make()->add('participant'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,9 @@ class ParticipantResource extends JsonResource
|
||||||
...$this->getModel()->getFields()->present(),
|
...$this->getModel()->getFields()->present(),
|
||||||
'created_at' => $this->created_at->format('Y-m-d H:i:s'),
|
'created_at' => $this->created_at->format('Y-m-d H:i:s'),
|
||||||
'created_at_display' => $this->created_at->format('d.m.Y'),
|
'created_at_display' => $this->created_at->format('d.m.Y'),
|
||||||
|
'links' => [
|
||||||
|
'destroy' => route('participant.destroy', ['participant' => $this->getModel()]),
|
||||||
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
|
<ui-popup v-if="deleting !== null" heading="Teilnehmer*in löschen?" @close="deleting = null">
|
||||||
|
<div>
|
||||||
|
<p class="mt-4">Den*Die Teilnehmer*in löschen?</p>
|
||||||
|
<div class="grid grid-cols-2 gap-3 mt-6">
|
||||||
|
<a href="#" class="text-center btn btn-danger" @click.prevent="handleDelete">Mitglied loschen</a>
|
||||||
|
<a href="#" class="text-center btn btn-primary" @click.prevent="deleting = null">Abbrechen</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ui-popup>
|
||||||
<page-filter breakpoint="lg">
|
<page-filter breakpoint="lg">
|
||||||
<f-multipleselect id="active_columns" v-model="activeColumnsConfig" :options="meta.columns" label="Aktive Spalten" size="sm" name="active_columns"></f-multipleselect>
|
<f-multipleselect id="active_columns" v-model="activeColumnsConfig" :options="meta.columns" label="Aktive Spalten" size="sm" name="active_columns"></f-multipleselect>
|
||||||
</page-filter>
|
</page-filter>
|
||||||
|
@ -9,13 +18,13 @@
|
||||||
<th></th>
|
<th></th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tr v-for="(form, index) in data" :key="index">
|
<tr v-for="(participant, index) in data" :key="index">
|
||||||
<td v-for="column in activeColumns" :key="column.id">
|
<td v-for="column in activeColumns" :key="column.id">
|
||||||
<div v-text="form[column.display_attribute]"></div>
|
<div v-text="participant[column.display_attribute]"></div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a v-tooltip="`Bearbeiten`" href="#" class="ml-2 inline-flex btn btn-warning btn-sm" @click.prevent="edit(form)"><ui-sprite src="pencil"></ui-sprite></a>
|
<a v-tooltip="`Bearbeiten`" href="#" class="ml-2 inline-flex btn btn-warning btn-sm" @click.prevent="edit(participant)"><ui-sprite src="pencil"></ui-sprite></a>
|
||||||
<a v-tooltip="`Löschen`" href="#" class="ml-2 inline-flex btn btn-danger btn-sm" @click.prevent="deleting = form"><ui-sprite src="trash"></ui-sprite></a>
|
<a v-tooltip="`Löschen`" href="#" class="ml-2 inline-flex btn btn-danger btn-sm" @click.prevent="deleting = participant"><ui-sprite src="trash"></ui-sprite></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -29,6 +38,8 @@
|
||||||
import {ref, computed} from 'vue';
|
import {ref, computed} from 'vue';
|
||||||
import {useApiIndex} from '../../composables/useApiIndex.js';
|
import {useApiIndex} from '../../composables/useApiIndex.js';
|
||||||
|
|
||||||
|
const deleting = ref(null);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
url: {
|
url: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -37,7 +48,7 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var {meta, data, reload, reloadPage, axios} = useApiIndex(props.url, 'participant');
|
var {meta, data, reload, reloadPage, axios, remove} = useApiIndex(props.url, 'participant');
|
||||||
|
|
||||||
const activeColumns = computed(() => meta.value.columns.filter((c) => meta.value.form_meta.active_columns.includes(c.id)));
|
const activeColumns = computed(() => meta.value.columns.filter((c) => meta.value.form_meta.active_columns.includes(c.id)));
|
||||||
|
|
||||||
|
@ -53,5 +64,10 @@ const activeColumnsConfig = computed({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function handleDelete() {
|
||||||
|
await remove(deleting.value);
|
||||||
|
deleting.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
await reload();
|
await reload();
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -31,6 +31,7 @@ use App\Form\Actions\FormtemplateUpdateAction;
|
||||||
use App\Form\Actions\FormUpdateAction;
|
use App\Form\Actions\FormUpdateAction;
|
||||||
use App\Form\Actions\FormUpdateMetaAction;
|
use App\Form\Actions\FormUpdateMetaAction;
|
||||||
use App\Form\Actions\IsDirtyAction;
|
use App\Form\Actions\IsDirtyAction;
|
||||||
|
use App\Form\Actions\ParticipantDestroyAction;
|
||||||
use App\Form\Actions\ParticipantIndexAction;
|
use App\Form\Actions\ParticipantIndexAction;
|
||||||
use App\Initialize\Actions\InitializeAction;
|
use App\Initialize\Actions\InitializeAction;
|
||||||
use App\Initialize\Actions\InitializeFormAction;
|
use App\Initialize\Actions\InitializeFormAction;
|
||||||
|
@ -162,4 +163,5 @@ Route::group(['middleware' => 'auth:web'], function (): void {
|
||||||
Route::patch('/form/{form}/meta', FormUpdateMetaAction::class)->name('form.update-meta');
|
Route::patch('/form/{form}/meta', FormUpdateMetaAction::class)->name('form.update-meta');
|
||||||
Route::get('/form/{form}/participants', ParticipantIndexAction::class)->name('form.participant.index');
|
Route::get('/form/{form}/participants', ParticipantIndexAction::class)->name('form.participant.index');
|
||||||
Route::post('/form/{form}/is-dirty', IsDirtyAction::class)->name('form.is-dirty');
|
Route::post('/form/{form}/is-dirty', IsDirtyAction::class)->name('form.is-dirty');
|
||||||
|
Route::delete('/participant/{participant}', ParticipantDestroyAction::class)->name('participant.destroy');
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Form;
|
||||||
|
|
||||||
|
use App\Form\Models\Form;
|
||||||
|
use App\Form\Models\Participant;
|
||||||
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
|
|
||||||
|
class ParticipantDestroyActionTest extends FormTestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
use DatabaseTransactions;
|
||||||
|
|
||||||
|
public function testItCanDestroyAParticipant(): void
|
||||||
|
{
|
||||||
|
$this->login()->loginNami()->withoutExceptionHandling();
|
||||||
|
$form = Form::factory()
|
||||||
|
->has(Participant::factory())
|
||||||
|
->sections([])
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$this->deleteJson(route('participant.destroy', ['participant' => $form->participants->first()]))
|
||||||
|
->assertOk();
|
||||||
|
|
||||||
|
$this->assertDatabaseCount('participants', 0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,7 @@ class ParticipantIndexActionTest extends FormTestCase
|
||||||
->assertJsonPath('data.0.birthday', '1991-04-20')
|
->assertJsonPath('data.0.birthday', '1991-04-20')
|
||||||
->assertJsonPath('data.0.select', ['A', 'B'])
|
->assertJsonPath('data.0.select', ['A', 'B'])
|
||||||
->assertJsonPath('data.0.select_display', 'A, B')
|
->assertJsonPath('data.0.select_display', 'A, B')
|
||||||
|
->assertJsonPath('data.0.links.destroy', route('participant.destroy', ['participant' => $form->participants->first()]))
|
||||||
->assertJsonPath('meta.columns.0.name', 'Vorname')
|
->assertJsonPath('meta.columns.0.name', 'Vorname')
|
||||||
->assertJsonPath('meta.columns.0.base_type', class_basename(TextField::class))
|
->assertJsonPath('meta.columns.0.base_type', class_basename(TextField::class))
|
||||||
->assertJsonPath('meta.columns.0.id', 'vorname')
|
->assertJsonPath('meta.columns.0.id', 'vorname')
|
||||||
|
|
Loading…
Reference in New Issue