Add mailman type with params

This commit is contained in:
Philipp Lang 2023-06-01 16:50:50 +02:00
parent f75201dfaa
commit a15b54f98d
10 changed files with 97 additions and 9 deletions

View File

@ -21,7 +21,7 @@ class StoreAction
return [
'name' => 'required|string|max:255',
'domain' => 'required|string|max:255',
'type.class' => ['required', 'string', 'max:255', Rule::in(app('mail-gateways'))],
'type.cls' => ['required', 'string', 'max:255', Rule::in(app('mail-gateways'))],
'type.params' => 'present',
];
}

View File

@ -18,7 +18,7 @@ class TypeCast implements CastsAttributes
{
$value = json_decode($value);
return new $value->class($value->params);
return new $value->cls($value->params);
}
/**

View File

@ -39,13 +39,20 @@ class MailgatewayResource extends JsonResource
'types' => app('mail-gateways')->map(fn ($gateway) => [
'id' => $gateway,
'name' => $gateway::name(),
'fields' => $gateway::fields(),
'defaults' => (object) $gateway::defaults(),
])->prepend([
'id' => null,
'name' => '-- kein --',
'fields' => [],
'defaults' => (object) [],
]),
'default' => [
'domain' => '',
'name' => '',
'type' => [
'params' => [],
'class' => null,
'cls' => null,
],
],
];

View File

@ -13,4 +13,9 @@ class LocalType extends Type
{
return true;
}
public static function fields(): array
{
return [];
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Mailgateway\Types;
class MailmanType extends Type
{
public static function name(): string
{
return 'Mailman';
}
public function works(): bool
{
return true;
}
public static function fields(): array
{
return [
[
'name' => 'url',
'label' => 'URL',
'type' => 'text',
'storeValidator' => 'required|max:255',
'updateValidator' => 'required|max:255',
'default' => '',
],
[
'name' => 'user',
'label' => 'Benutzer',
'type' => 'text',
'storeValidator' => 'required|max:255',
'updateValidator' => 'required|max:255',
'default' => '',
],
[
'name' => 'password',
'label' => 'Passwort',
'type' => 'text',
'storeValidator' => 'required|max:255',
'updateValidator' => 'nullable|max:255',
'default' => '',
],
];
}
}

View File

@ -6,5 +6,14 @@ abstract class Type
{
abstract public static function name(): string;
abstract public static function fields(): array;
abstract public function works(): bool;
public static function defaults(): array
{
return collect(static::fields())->mapWithKeys(fn ($field) => [
$field['name'] => $field['default'],
])->toArray();
}
}

View File

@ -3,6 +3,7 @@
namespace App\Providers;
use App\Mailgateway\Types\LocalType;
use App\Mailgateway\Types\MailmanType;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\ServiceProvider;
@ -30,6 +31,7 @@ class AppServiceProvider extends ServiceProvider
app()->bind('mail-gateways', fn () => collect([
LocalType::class,
MailmanType::class,
]));
}

View File

@ -23,7 +23,7 @@ class MailgatewayFactory extends Factory
return [
'name' => $this->faker->words(5, true),
'type' => [
'class' => app('mail-gateways')->random(),
'cls' => app('mail-gateways')->random(),
'params' => [],
],
'domain' => $this->faker->safeEmailDomain(),
@ -37,7 +37,7 @@ class MailgatewayFactory extends Factory
public function type(string $type, array $params): self
{
return $this->state(['type' => [
'class' => $type,
'cls' => $type,
'params' => $params,
]]);
}

View File

@ -1,14 +1,30 @@
<template>
<page-layout>
<template #toolbar>
<page-toolbar-button @click.prevent="model = data.meta.default" color="primary" icon="plus">Neue Verbindung</page-toolbar-button>
<page-toolbar-button @click.prevent="model = {...data.meta.default}" color="primary" icon="plus">Neue Verbindung</page-toolbar-button>
</template>
<ui-popup heading="Neue Verbindung" v-if="model !== null && !model.id" @close="model = null">
<div>
<div class="grid grid-cols-2 gap-3 mt-6">
<f-text v-model="model.name" name="name" id="name" label="Bezeichnung" required></f-text>
<f-text v-model="model.domain" name="domain" id="domain" label="Domain" required></f-text>
<f-select :value="model.type.class" @input="model.type.class = $event" label="Typ" name="type" id="type" :options="data.meta.types"></f-select>
<f-select
:value="model.type.cls"
@input="
model.type = {
cls: $event,
params: {...getType($event).defaults},
}
"
label="Typ"
name="type"
id="type"
:options="data.meta.types"
:placeholder="''"
></f-select>
<template v-for="(field, index) in getType(model.type.cls).fields">
<f-text :key="index" v-if="field.type === 'text'" :label="field.label" :name="field.name" :id="field.name" v-model="model.type.params[field.name]"></f-text>
</template>
</div>
<div class="flex mt-4 space-x-2">
<a href="#" @click.prevent="submit" class="text-center btn btn-danger">Speichern</a>
@ -68,6 +84,9 @@ export default {
},
methods: {
getType(type) {
return this.data.meta.types.find((t) => t.id === type);
},
async submit() {
try {
await this.axios.post(this.data.meta.links.store, this.model);

View File

@ -11,7 +11,7 @@ class MailgatewayRequestFactory extends RequestFactory
return [
'name' => $this->faker->words(5, true),
'type' => [
'class' => app('mail-gateways')->random(),
'cls' => app('mail-gateways')->random(),
'params' => [],
],
'domain' => $this->faker->safeEmailDomain(),
@ -35,7 +35,7 @@ class MailgatewayRequestFactory extends RequestFactory
public function type(string $type, array $params): self
{
return $this->state(['type' => [
'class' => $type,
'cls' => $type,
'params' => $params,
]]);
}