Compare commits
7 Commits
0080a54aaf
...
d38989f302
Author | SHA1 | Date |
---|---|---|
philipp lang | d38989f302 | |
philipp lang | a434388bcb | |
philipp lang | 48d9d9cc92 | |
philipp lang | c2016af587 | |
philipp lang | 4057f9fc8d | |
philipp lang | 89f5489e86 | |
philipp lang | 7497593bb2 |
|
@ -17,7 +17,6 @@ class CreateAction
|
|||
session()->put('title', 'Mail-Verteiler erstellen');
|
||||
|
||||
return Inertia::render('maildispatcher/MaildispatcherForm', [
|
||||
'mode' => 'create',
|
||||
'meta' => MaildispatcherResource::meta(),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Maildispatcher\Actions;
|
||||
|
||||
use App\Maildispatcher\Models\Maildispatcher;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class DestroyAction
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
public function handle(Maildispatcher $maildispatcher): void
|
||||
{
|
||||
$maildispatcher->delete();
|
||||
}
|
||||
|
||||
public function asController(Maildispatcher $maildispatcher): RedirectResponse
|
||||
{
|
||||
$this->handle($maildispatcher);
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Maildispatcher\Actions;
|
||||
|
||||
use App\Maildispatcher\Models\Maildispatcher;
|
||||
use App\Maildispatcher\Resources\MaildispatcherResource;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class EditAction
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
public function asController(Maildispatcher $maildispatcher): Response
|
||||
{
|
||||
session()->put('menu', 'maildispatcher');
|
||||
session()->put('title', 'Mail-Verteiler bearbeiten');
|
||||
|
||||
return Inertia::render('maildispatcher/MaildispatcherForm', [
|
||||
'data' => new MaildispatcherResource($maildispatcher),
|
||||
'meta' => MaildispatcherResource::meta(),
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -13,13 +13,16 @@ class ResyncAction
|
|||
{
|
||||
use AsAction;
|
||||
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
foreach (Maildispatcher::get() as $dispatcher) {
|
||||
$dispatcher->gateway->type->sync($dispatcher->name, $dispatcher->gateway->domain, $this->getResults($dispatcher));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, MailEntry>
|
||||
*/
|
||||
public function getResults(Maildispatcher $dispatcher): Collection
|
||||
{
|
||||
return Member::search(data_get($dispatcher->filter, 'search', ''))->query(
|
||||
|
|
|
@ -23,6 +23,19 @@ class StoreAction
|
|||
ResyncAction::dispatch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getValidationAttributes(): array
|
||||
{
|
||||
return [
|
||||
'gateway_id' => 'Verbindung',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace App\Maildispatcher\Actions;
|
||||
|
||||
use App\Maildispatcher\Models\Maildispatcher;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Lorisleiva\Actions\ActionRequest;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class UpdateAction
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
*/
|
||||
public function handle(Maildispatcher $maildispatcher, array $input): void
|
||||
{
|
||||
$maildispatcher->update([
|
||||
...$input,
|
||||
'filter' => (object) $input['filter'],
|
||||
]);
|
||||
ResyncAction::dispatch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getValidationAttributes(): array
|
||||
{
|
||||
return [
|
||||
'gateway_id' => 'Verbindung',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'gateway_id' => 'required|exists:mailgateways,id',
|
||||
'name' => 'required|max:50',
|
||||
'filter' => 'present|array',
|
||||
];
|
||||
}
|
||||
|
||||
public function asController(Maildispatcher $maildispatcher, ActionRequest $request): JsonResponse
|
||||
{
|
||||
$this->handle($maildispatcher, $request->validated());
|
||||
|
||||
return response()->json('', 201);
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ namespace App\Maildispatcher\Models;
|
|||
use Illuminate\Database\Eloquent\Concerns\HasUuids;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Localmaildispatcher extends Model
|
||||
{
|
||||
|
@ -15,9 +14,4 @@ class Localmaildispatcher extends Model
|
|||
public $guarded = [];
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
public function dispatcher(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Maildispatcher::class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,18 @@ class Maildispatcher extends Model
|
|||
'filter' => 'json',
|
||||
];
|
||||
|
||||
public static function booted(): void
|
||||
{
|
||||
static::deleting(function ($dispatcher) {
|
||||
foreach ($dispatcher->gateway->type->list($dispatcher->name, $dispatcher->gateway->domain) as $email) {
|
||||
$dispatcher->gateway->type->remove($dispatcher->name, $dispatcher->gateway->domain, $email->email);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo<Mailgateway, self>
|
||||
*/
|
||||
public function gateway(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Mailgateway::class);
|
||||
|
|
|
@ -2,16 +2,17 @@
|
|||
|
||||
namespace App\Maildispatcher\Resources;
|
||||
|
||||
use App\Activity;
|
||||
use App\Group;
|
||||
use App\Lib\HasMeta;
|
||||
use App\Maildispatcher\Models\Maildispatcher;
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use App\Mailgateway\Resources\MailgatewayResource;
|
||||
use App\Member\FilterScope;
|
||||
use App\Member\Member;
|
||||
use App\Subactivity;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/**
|
||||
* @mixin Maildispatcher
|
||||
*/
|
||||
class MaildispatcherResource extends JsonResource
|
||||
{
|
||||
use HasMeta;
|
||||
|
@ -21,13 +22,21 @@ class MaildispatcherResource extends JsonResource
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'gateway' => new MailgatewayResource($this->whenLoaded('gateway')),
|
||||
'gateway_id' => $this->gateway_id,
|
||||
'filter' => $this->filter,
|
||||
'id' => $this->id,
|
||||
'links' => [
|
||||
'edit' => route('maildispatcher.edit', ['maildispatcher' => $this->getModel()]),
|
||||
'update' => route('maildispatcher.update', ['maildispatcher' => $this->getModel()]),
|
||||
'delete' => route('maildispatcher.destroy', ['maildispatcher' => $this->getModel()]),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -46,10 +55,7 @@ class MaildispatcherResource extends JsonResource
|
|||
'gateway_id' => null,
|
||||
'filter' => FilterScope::from([])->toArray(),
|
||||
],
|
||||
'activities' => Activity::pluck('name', 'id'),
|
||||
'subactivities' => Subactivity::pluck('name', 'id'),
|
||||
'members' => Member::ordered()->get()->map(fn ($member) => ['id' => $member->id, 'name' => $member->fullname]),
|
||||
'groups' => Group::pluck('name', 'id'),
|
||||
'gateways' => Mailgateway::pluck('name', 'id'),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ use Lorisleiva\Actions\ActionRequest;
|
|||
|
||||
trait ValidatesRequests
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
*/
|
||||
public function checkIfWorks(array $input): void
|
||||
{
|
||||
if (!app(data_get($input, 'type.cls'))->setParams($input['type']['params'])->works()) {
|
||||
|
|
|
@ -2,8 +2,12 @@
|
|||
|
||||
namespace App\Mailgateway\Casts;
|
||||
|
||||
use App\Mailgateway\Types\Type;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
/**
|
||||
* @implements CastsAttributes<Type, Type>
|
||||
*/
|
||||
class TypeCast implements CastsAttributes
|
||||
{
|
||||
/**
|
||||
|
@ -11,6 +15,7 @@ class TypeCast implements CastsAttributes
|
|||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param mixed $value
|
||||
* @param array<string, mixed> $attributes
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
|
@ -26,6 +31,7 @@ class TypeCast implements CastsAttributes
|
|||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param mixed $value
|
||||
* @param array<string, mixed> $attributes
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,7 @@ class MailgatewayResource extends JsonResource
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
|
@ -35,6 +35,9 @@ class MailgatewayResource extends JsonResource
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function meta(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
@ -32,6 +32,9 @@ abstract class Type
|
|||
*/
|
||||
abstract public function setParams(array $params): static;
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function defaults(): array
|
||||
{
|
||||
return collect(static::fields())->mapWithKeys(fn ($field) => [
|
||||
|
@ -39,6 +42,9 @@ abstract class Type
|
|||
])->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, MailgatewayParsedCustomField>
|
||||
*/
|
||||
public static function presentFields(string $validator): array
|
||||
{
|
||||
return array_map(fn ($field) => [
|
||||
|
@ -47,6 +53,9 @@ abstract class Type
|
|||
], static::fields());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function rules(string $validator): array
|
||||
{
|
||||
return collect(static::fields())->mapWithKeys(fn ($field) => [
|
||||
|
@ -54,6 +63,9 @@ abstract class Type
|
|||
])->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<string, mixed>>
|
||||
*/
|
||||
public function toResource(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
@ -85,7 +85,7 @@ class MailmanService
|
|||
{
|
||||
$response = $this->http()->delete("members/{$member->memberId}");
|
||||
|
||||
throw_unless($response->ok(), MailmanServiceException::class, 'Removing member failed');
|
||||
throw_unless(204 === $response->status(), MailmanServiceException::class, 'Removing member failed');
|
||||
}
|
||||
|
||||
private function http(): PendingRequest
|
||||
|
|
|
@ -27,7 +27,7 @@ class FilterScope extends Filter
|
|||
public ?string $billKind = null,
|
||||
public array $activityIds = [],
|
||||
public array $subactivityIds = [],
|
||||
public string $search = '',
|
||||
public ?string $search = '',
|
||||
public array $groupIds = [],
|
||||
public array $additional = [],
|
||||
) {
|
||||
|
|
|
@ -140,6 +140,7 @@ class MemberResource extends JsonResource
|
|||
'genders' => Gender::pluck('name', 'id'),
|
||||
'billKinds' => BillKind::forSelect(),
|
||||
'nationalities' => Nationality::pluck('name', 'id'),
|
||||
'members' => Member::ordered()->get()->map(fn ($member) => ['id' => $member->id, 'name' => $member->fullname]),
|
||||
'links' => [
|
||||
'index' => route('member.index'),
|
||||
'create' => route('member.create'),
|
||||
|
|
41
phpstan.neon
41
phpstan.neon
|
@ -19,6 +19,7 @@ parameters:
|
|||
ContributionRequestArray: 'array{dateFrom: string, dateUntil: string, zipLocation: string, country: int, eventName: string, members: array<int, int>}'
|
||||
ContributionApiRequestArray: 'array{dateFrom: string, dateUntil: string, zipLocation: string, country: int, eventName: string, member_data: array<int, ContributionMemberData>}'
|
||||
MailgatewayCustomField: 'array{name: string, label: string, type: string, storeValidator: string, updateValidator: string, default: string}'
|
||||
MailgatewayParsedCustomField: 'array{name: string, label: string, type: string, storeValidator: string, updateValidator: string, default: string, is_required: bool}'
|
||||
|
||||
ignoreErrors:
|
||||
-
|
||||
|
@ -634,3 +635,43 @@ parameters:
|
|||
message: "#^Return type of call to method Illuminate\\\\Support\\\\Collection\\<int,class\\-string\\<App\\\\Setting\\\\LocalSettings\\>\\>\\:\\:map\\(\\) contains unresolvable type\\.$#"
|
||||
count: 1
|
||||
path: app/Setting/SettingFactory.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$email\\.$#"
|
||||
count: 2
|
||||
path: app/Maildispatcher/Actions/ResyncAction.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$email_parents\\.$#"
|
||||
count: 2
|
||||
path: app/Maildispatcher/Actions/ResyncAction.php
|
||||
|
||||
-
|
||||
message: "#^Unable to resolve the template type TKey in call to function collect$#"
|
||||
count: 2
|
||||
path: app/Mailgateway/Actions/StoreAction.php
|
||||
|
||||
-
|
||||
message: "#^Unable to resolve the template type TValue in call to function collect$#"
|
||||
count: 2
|
||||
path: app/Mailgateway/Actions/StoreAction.php
|
||||
|
||||
-
|
||||
message: "#^Unable to resolve the template type TKey in call to function collect$#"
|
||||
count: 2
|
||||
path: app/Mailgateway/Actions/UpdateAction.php
|
||||
|
||||
-
|
||||
message: "#^Unable to resolve the template type TValue in call to function collect$#"
|
||||
count: 2
|
||||
path: app/Mailgateway/Actions/UpdateAction.php
|
||||
|
||||
-
|
||||
message: "#^Return type of call to method Illuminate\\\\Support\\\\Collection\\<\\(int\\|string\\),mixed\\>\\:\\:map\\(\\) contains unresolvable type\\.$#"
|
||||
count: 1
|
||||
path: app/Mailgateway/Resources/MailgatewayResource.php
|
||||
|
||||
-
|
||||
message: "#^Generic type Illuminate\\\\Pagination\\\\LengthAwarePaginator\\<int, App\\\\Member\\\\Member\\> in PHPDoc tag @return specifies 2 template types, but class Illuminate\\\\Pagination\\\\LengthAwarePaginator supports only 1\\: TValue$#"
|
||||
count: 1
|
||||
path: app/Member/Actions/SearchAction.php
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
class="flex items-center border-gray-600 text-gray-300 leading-none border-solid bg-gray-700 w-full appearance-none outline-none rounded-lg size-sm text-xs px-1 border pr-6"
|
||||
v-text="`${value.length} Einträge ausgewählt`"
|
||||
></div>
|
||||
<div v-show="visible" class="absolute w-[max-content] z-30 h-[31rem] overflow-auto shadow-lg bg-gray-600 border border-gray-500 rounded-lg p-2 top-7">
|
||||
<div v-show="visible" class="absolute w-[max-content] z-30 max-h-[31rem] overflow-auto shadow-lg bg-gray-600 border border-gray-500 rounded-lg p-2 top-7">
|
||||
<div v-for="(option, index) in parsedOptions" class="flex items-center space-x-2" :key="index">
|
||||
<f-switch :id="`${id}-${index}`" size="sm" :items="value.includes(option.id)" :value="option.id" @input="trigger(option, $event)"></f-switch>
|
||||
<div class="text-sm text-gray-200" v-text="option.name"></div>
|
||||
|
|
|
@ -8,12 +8,7 @@
|
|||
<select :disabled="disabled" :name="name" :value="value" @change="trigger">
|
||||
<option v-if="placeholder" v-html="placeholder" :value="null"></option>
|
||||
|
||||
<option
|
||||
v-for="option in parsedOptions"
|
||||
:key="option.id"
|
||||
v-html="option.name"
|
||||
:value="option.id"
|
||||
></option>
|
||||
<option v-for="option in parsedOptions" :key="option.id" v-html="option.name" :value="option.id"></option>
|
||||
</select>
|
||||
<div class="info-wrap">
|
||||
<div v-if="hint" v-tooltip="hint">
|
||||
|
@ -95,10 +90,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
trigger(v) {
|
||||
this.$emit(
|
||||
'input',
|
||||
isNaN(parseInt(v.target.value)) ? (v.target.value ? v.target.value : null) : parseInt(v.target.value)
|
||||
);
|
||||
this.$emit('input', /^[0-9]+$/.test(v.target.value) ? parseInt(v.target.value) : v.target.value ? v.target.value : null);
|
||||
},
|
||||
clear() {
|
||||
this.$emit('input', null);
|
||||
|
@ -119,12 +111,6 @@ export default {
|
|||
|
||||
<style scope>
|
||||
.inset-bg {
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
hsl(247.5, 66.7%, 97.6%) 0%,
|
||||
hsl(247.5, 66.7%, 97.6%) 41%,
|
||||
hsl(0deg 0% 100%) 41%,
|
||||
hsl(180deg 0% 100%) 100%
|
||||
);
|
||||
background: linear-gradient(to bottom, hsl(247.5, 66.7%, 97.6%) 0%, hsl(247.5, 66.7%, 97.6%) 41%, hsl(0deg 0% 100%) 41%, hsl(180deg 0% 100%) 100%);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -11,12 +11,12 @@
|
|||
<f-select id="gateway_id" name="gateway_id" :options="meta.gateways" v-model="model.gateway_id" label="Verbindung" size="sm" required></f-select>
|
||||
</div>
|
||||
</ui-box>
|
||||
<ui-box heading="Filterregeln">
|
||||
<ui-box heading="Filterregeln" v-if="members !== null">
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<f-multipleselect
|
||||
id="activity_ids"
|
||||
name="activity_ids"
|
||||
:options="meta.activities"
|
||||
:options="members.meta.filterActivities"
|
||||
v-model="model.filter.activity_ids"
|
||||
@input="reload(1)"
|
||||
label="Tätigkeit"
|
||||
|
@ -25,7 +25,7 @@
|
|||
<f-multipleselect
|
||||
id="subactivity_ids"
|
||||
name="subactivity_ids"
|
||||
:options="meta.subactivities"
|
||||
:options="members.meta.filterSubactivities"
|
||||
v-model="model.filter.subactivity_ids"
|
||||
@input="reload(1)"
|
||||
label="Unterttätigkeit"
|
||||
|
@ -34,13 +34,21 @@
|
|||
<f-multipleselect
|
||||
id="additional"
|
||||
name="additional"
|
||||
:options="meta.members"
|
||||
:options="members.meta.members"
|
||||
v-model="model.filter.additional"
|
||||
@input="reload(1)"
|
||||
label="Zusätzliche Mitglieder"
|
||||
size="sm"
|
||||
></f-multipleselect>
|
||||
<f-multipleselect id="groupIds" name="groupIds" :options="meta.groups" v-model="model.filter.group_ids" @input="reload(1)" label="Gruppierungen" size="sm"></f-multipleselect>
|
||||
<f-multipleselect
|
||||
id="groupIds"
|
||||
name="groupIds"
|
||||
:options="members.meta.groups"
|
||||
v-model="model.filter.group_ids"
|
||||
@input="reload(1)"
|
||||
label="Gruppierungen"
|
||||
size="sm"
|
||||
></f-multipleselect>
|
||||
</div>
|
||||
</ui-box>
|
||||
<ui-box heading="Mitglieder" v-if="members !== null">
|
||||
|
@ -69,20 +77,20 @@
|
|||
|
||||
<script>
|
||||
import indexHelpers from '../../mixins/indexHelpers.js';
|
||||
import hasFlash from '../../mixins/hasFlash.js';
|
||||
|
||||
export default {
|
||||
mixins: [indexHelpers],
|
||||
mixins: [indexHelpers, hasFlash],
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
model: this.mode === 'create' ? {...this.meta.default_model} : {...this.data},
|
||||
model: this.data === undefined ? {...this.meta.default_model} : {...this.data},
|
||||
members: null,
|
||||
};
|
||||
},
|
||||
|
||||
props: {
|
||||
data: {},
|
||||
mode: {},
|
||||
meta: {},
|
||||
},
|
||||
|
||||
|
@ -95,6 +103,15 @@ export default {
|
|||
})
|
||||
).data;
|
||||
},
|
||||
|
||||
async submit() {
|
||||
try {
|
||||
this.model.id ? await this.axios.patch(this.model.links.update, this.model) : await this.axios.post('/maildispatcher', this.model);
|
||||
this.$inertia.visit(this.meta.links.index);
|
||||
} catch (e) {
|
||||
this.errorsFromException(e);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
async created() {
|
||||
|
|
|
@ -3,11 +3,20 @@
|
|||
<template #toolbar>
|
||||
<page-toolbar-button :href="data.meta.links.create" color="primary" icon="plus">Verteiler erstellen</page-toolbar-button>
|
||||
</template>
|
||||
<ui-popup heading="Verteiler löschen?" v-if="deleting !== null" @close="deleting.reject()">
|
||||
<div>
|
||||
<p class="mt-4">Den Verteiler "{{ deleting.dispatcher.name }}" löschen?</p>
|
||||
<div class="grid grid-cols-2 gap-3 mt-6">
|
||||
<a href="#" @click.prevent="deleting.resolve()" class="text-center btn btn-danger">Löschen</a>
|
||||
<a href="#" @click.prevent="deleting.reject()" class="text-center btn btn-primary">Abbrechen</a>
|
||||
</div>
|
||||
</div>
|
||||
</ui-popup>
|
||||
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm">
|
||||
<thead>
|
||||
<th>Name</th>
|
||||
<th>Interner Beitrag</th>
|
||||
<th>Nami-Beitrag</th>
|
||||
<th>Domain</th>
|
||||
<th>Verbindung</th>
|
||||
<th></th>
|
||||
</thead>
|
||||
|
||||
|
@ -16,13 +25,14 @@
|
|||
<div v-text="dispatcher.name"></div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-text="dispatcher.amount_human"></div>
|
||||
<div v-text="dispatcher.gateway.domain"></div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-text="dispatcher.fee_name"></div>
|
||||
<div v-text="dispatcher.gateway.name"></div>
|
||||
</td>
|
||||
<td>
|
||||
<i-link :href="`/dispatcher/${dispatcher.id}/edit`" class="inline-flex btn btn-warning btn-sm"><svg-sprite src="pencil"></svg-sprite></i-link>
|
||||
<i-link :href="dispatcher.links.edit" class="mr-1 inline-flex btn btn-warning btn-sm"><svg-sprite src="pencil"></svg-sprite></i-link>
|
||||
<i-link @click.prevent="remove(dispatcher)" class="inline-flex btn btn-danger btn-sm"><svg-sprite src="trash"></svg-sprite></i-link>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -31,6 +41,25 @@
|
|||
|
||||
<script>
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
deleting: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async remove(dispatcher) {
|
||||
new Promise((resolve, reject) => {
|
||||
this.deleting = {resolve, reject, dispatcher};
|
||||
})
|
||||
.then(() => {
|
||||
this.$inertia.delete(dispatcher.links.delete);
|
||||
this.deleting = null;
|
||||
})
|
||||
.catch(() => {
|
||||
this.deleting = null;
|
||||
});
|
||||
},
|
||||
},
|
||||
props: {
|
||||
data: {},
|
||||
},
|
||||
|
|
|
@ -21,8 +21,11 @@ use App\Initialize\Actions\NamiGetSearchLayerAction;
|
|||
use App\Initialize\Actions\NamiLoginCheckAction;
|
||||
use App\Initialize\Actions\NamiSearchAction;
|
||||
use App\Maildispatcher\Actions\CreateAction;
|
||||
use App\Maildispatcher\Actions\DestroyAction;
|
||||
use App\Maildispatcher\Actions\EditAction;
|
||||
use App\Maildispatcher\Actions\IndexAction;
|
||||
use App\Maildispatcher\Actions\StoreAction as MaildispatcherStoreAction;
|
||||
use App\Maildispatcher\Actions\UpdateAction as MaildispatcherUpdateAction;
|
||||
use App\Mailgateway\Actions\StoreAction;
|
||||
use App\Mailgateway\Actions\UpdateAction;
|
||||
use App\Member\Actions\ExportAction;
|
||||
|
@ -89,5 +92,8 @@ Route::group(['middleware' => 'auth:web'], function (): void {
|
|||
Route::patch('/api/mailgateway/{mailgateway}', UpdateAction::class)->name('mailgateway.update');
|
||||
Route::get('/maildispatcher', IndexAction::class)->name('maildispatcher.index');
|
||||
Route::get('/maildispatcher/create', CreateAction::class)->name('maildispatcher.create');
|
||||
Route::get('/maildispatcher/{maildispatcher}', EditAction::class)->name('maildispatcher.edit');
|
||||
Route::patch('/maildispatcher/{maildispatcher}', MaildispatcherUpdateAction::class)->name('maildispatcher.update');
|
||||
Route::post('/maildispatcher', MaildispatcherStoreAction::class)->name('maildispatcher.store');
|
||||
Route::delete('/maildispatcher/{maildispatcher}', DestroyAction::class)->name('maildispatcher.destroy');
|
||||
});
|
||||
|
|
|
@ -29,17 +29,17 @@ class StoreTest extends TestCase
|
|||
Member::factory()->defaults()->has(Membership::factory()->inLocal('Leiter*in', 'Wölfling'))->create(['email' => 'jane@example.com']);
|
||||
$activityId = Activity::first()->id;
|
||||
|
||||
$response = $this->postJson('/api/maildispatcher', [
|
||||
$response = $this->postJson('/maildispatcher', [
|
||||
'name' => 'test',
|
||||
'gateway_id' => $gateway->id,
|
||||
'filter' => ['activity_id' => $activityId],
|
||||
'filter' => ['activity_ids' => [$activityId]],
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$this->assertDatabaseHas('maildispatchers', [
|
||||
'name' => 'test',
|
||||
'gateway_id' => $gateway->id,
|
||||
'filter' => "{\"activity_id\":{$activityId}}",
|
||||
'filter' => "{\"activity_ids\":[{$activityId}]}",
|
||||
]);
|
||||
$dispatcher = Maildispatcher::first();
|
||||
$this->assertDatabaseCount('localmaildispatchers', 1);
|
||||
|
|
|
@ -194,12 +194,12 @@ class IndexTest extends TestCase
|
|||
Member::factory()->defaults()->for($group1)->create();
|
||||
Member::factory()->defaults()->for($group1)->create();
|
||||
|
||||
$oneResponse = $this->callFilter('member.index', ['group_id' => $group1->id]);
|
||||
$twoResponse = $this->callFilter('member.index', ['group_id' => $group2->id]);
|
||||
$oneResponse = $this->callFilter('member.index', ['group_ids' => [$group1->id]]);
|
||||
$twoResponse = $this->callFilter('member.index', ['group_ids' => [$group2->id]]);
|
||||
|
||||
$this->assertCount(3, $this->inertia($oneResponse, 'data.data'));
|
||||
$this->assertCount(0, $this->inertia($twoResponse, 'data.data'));
|
||||
$this->assertInertiaHas($group1->id, $oneResponse, 'data.meta.filter.group_id');
|
||||
$this->assertInertiaHas([$group1->id], $oneResponse, 'data.meta.filter.group_ids');
|
||||
}
|
||||
|
||||
public function testItFiltersForAusstand(): void
|
||||
|
|
Loading…
Reference in New Issue