Compare commits
14 Commits
af848e51c6
...
bf7a298afc
Author | SHA1 | Date |
---|---|---|
philipp lang | bf7a298afc | |
philipp lang | 7a1ab8f03b | |
philipp lang | afffecb4c0 | |
philipp lang | 1c7e010249 | |
philipp lang | 644a70a082 | |
philipp lang | e6d33ba2de | |
philipp lang | c67ae040de | |
philipp lang | 54b413ae68 | |
philipp lang | d6325fbc33 | |
philipp lang | 3ff185e059 | |
philipp lang | 0d412544bb | |
philipp lang | 201b99cacf | |
philipp lang | bf0e9cb962 | |
philipp lang | 3bc038c4c1 |
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Maildispatcher\Models;
|
||||
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use Modules\Mailgateway\Models\Mailgateway;
|
||||
use Database\Factories\Maildispatcher\Models\MaildispatcherFactory;
|
||||
use Illuminate\Database\Eloquent\Concerns\HasUuids;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
|
|
@ -4,8 +4,7 @@ namespace App\Maildispatcher\Resources;
|
|||
|
||||
use App\Lib\HasMeta;
|
||||
use App\Maildispatcher\Models\Maildispatcher;
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use App\Mailgateway\Resources\MailgatewayResource;
|
||||
use Modules\Mailgateway\Models\Mailgateway;
|
||||
use App\Member\FilterScope;
|
||||
use App\Member\Member;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mailgateway\Actions;
|
||||
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use Lorisleiva\Actions\ActionRequest;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class StoreAction
|
||||
{
|
||||
use AsAction;
|
||||
use ValidatesRequests;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
*/
|
||||
public function handle(array $input): void
|
||||
{
|
||||
$this->checkIfWorks($input);
|
||||
Mailgateway::create($input);
|
||||
}
|
||||
|
||||
public function asController(ActionRequest $request): void
|
||||
{
|
||||
$this->handle($request->validated());
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mailgateway\Actions;
|
||||
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use Lorisleiva\Actions\ActionRequest;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class UpdateAction
|
||||
{
|
||||
use AsAction;
|
||||
use ValidatesRequests;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
*/
|
||||
public function handle(Mailgateway $mailgateway, array $input): void
|
||||
{
|
||||
$this->checkIfWorks($input);
|
||||
|
||||
$mailgateway->update($input);
|
||||
}
|
||||
|
||||
public function asController(Mailgateway $mailgateway, ActionRequest $request): void
|
||||
{
|
||||
$this->handle($mailgateway, $request->validated());
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mailgateway\Actions;
|
||||
|
||||
use App\Mailgateway\Types\Type;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
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()) {
|
||||
throw ValidationException::withMessages(['connection' => 'Verbindung fehlgeschlagen.']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'domain' => 'required|string|max:255',
|
||||
...$this->typeValidation(),
|
||||
'type.params' => 'present|array',
|
||||
...collect(request()->input('type.cls')::rules('storeValidator'))->mapWithKeys(fn ($rules, $key) => ["type.params.{$key}" => $rules]),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getValidationAttributes(): array
|
||||
{
|
||||
return [
|
||||
'type.cls' => 'Typ',
|
||||
'name' => 'Beschreibung',
|
||||
'domain' => 'Domain',
|
||||
...collect(request()->input('type.cls')::fieldNames())->mapWithKeys(fn ($attribute, $key) => ["type.params.{$key}" => $attribute]),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function typeValidation(): array
|
||||
{
|
||||
return [
|
||||
'type.cls' => ['required', 'string', 'max:255', Rule::in(app('mail-gateways'))],
|
||||
];
|
||||
}
|
||||
|
||||
public function prepareForValidation(ActionRequest $request): void
|
||||
{
|
||||
if (!is_subclass_of(request()->input('type.cls'), Type::class)) {
|
||||
throw ValidationException::withMessages(['type.cls' => 'Typ ist nicht valide.']);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mailgateway\Casts;
|
||||
|
||||
use App\Mailgateway\Types\Type;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
/**
|
||||
* @implements CastsAttributes<Type, Type>
|
||||
*/
|
||||
class TypeCast implements CastsAttributes
|
||||
{
|
||||
/**
|
||||
* Cast the given value.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param mixed $value
|
||||
* @param array<string, mixed> $attributes
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
{
|
||||
$value = json_decode($value, true);
|
||||
|
||||
return app($value['cls'])->setParams($value['params']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the given value for storage.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param mixed $value
|
||||
* @param array<string, mixed> $attributes
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
return json_encode($value);
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mailgateway;
|
||||
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use App\Mailgateway\Resources\MailgatewayResource;
|
||||
use App\Setting\LocalSettings;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
class MailgatewaySettings extends LocalSettings
|
||||
{
|
||||
public static function group(): string
|
||||
{
|
||||
return 'mailgateway';
|
||||
}
|
||||
|
||||
public static function title(): string
|
||||
{
|
||||
return 'E-Mail-Verbindungen';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function viewData(): array
|
||||
{
|
||||
return [
|
||||
'data' => MailgatewayResource::collection(Mailgateway::paginate(10)),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mailgateway\Resources;
|
||||
|
||||
use App\Lib\HasMeta;
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/**
|
||||
* @mixin Mailgateway
|
||||
* @deprecated
|
||||
*/
|
||||
class MailgatewayResource extends JsonResource
|
||||
{
|
||||
use HasMeta;
|
||||
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'domain' => $this->domain,
|
||||
'type_human' => $this->type::name(),
|
||||
'works' => $this->type->works(),
|
||||
'type' => $this->type->toResource(),
|
||||
'id' => $this->id,
|
||||
'links' => [
|
||||
'update' => route('mailgateway.update', ['mailgateway' => $this->getModel()]),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function meta(): array
|
||||
{
|
||||
return [
|
||||
'links' => [
|
||||
'store' => route('mailgateway.store'),
|
||||
],
|
||||
'types' => app('mail-gateways')->map(fn ($gateway) => [
|
||||
'id' => $gateway,
|
||||
'name' => $gateway::name(),
|
||||
'fields' => $gateway::presentFields('storeValidator'),
|
||||
'defaults' => (object) $gateway::defaults(),
|
||||
])->prepend([
|
||||
'id' => null,
|
||||
'name' => '-- kein --',
|
||||
'fields' => [],
|
||||
'defaults' => (object) [],
|
||||
]),
|
||||
'default' => [
|
||||
'domain' => '',
|
||||
'name' => '',
|
||||
'type' => [
|
||||
'params' => [],
|
||||
'cls' => null,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -3,13 +3,10 @@
|
|||
namespace App\Providers;
|
||||
|
||||
use App\Form\Models\Form;
|
||||
use App\Mailgateway\Types\LocalType;
|
||||
use App\Mailgateway\Types\MailmanType;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Laravel\Telescope\Telescope;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
@ -30,11 +27,6 @@ class AppServiceProvider extends ServiceProvider
|
|||
return $this;
|
||||
});
|
||||
|
||||
app()->bind('mail-gateways', fn () => collect([
|
||||
LocalType::class,
|
||||
MailmanType::class,
|
||||
]));
|
||||
|
||||
app()->extend('media-library-helpers', fn ($p) => $p->put('form', Form::class));
|
||||
|
||||
Blade::componentNamespace('App\\View\\Mail', 'mail-view');
|
||||
|
|
|
@ -3,14 +3,10 @@
|
|||
namespace App\Setting;
|
||||
|
||||
use App\Group;
|
||||
use App\Initialize\Actions\NamiLoginCheckAction;
|
||||
use App\Nami\Actions\SettingSaveAction;
|
||||
use App\Setting\Contracts\Storeable;
|
||||
use Lorisleiva\Actions\ActionRequest;
|
||||
use Zoomyboy\LaravelNami\Api;
|
||||
use Zoomyboy\LaravelNami\Nami;
|
||||
|
||||
class NamiSettings extends LocalSettings implements Storeable
|
||||
class NamiSettings extends LocalSettings
|
||||
{
|
||||
public int $mglnr;
|
||||
|
||||
|
@ -43,14 +39,6 @@ class NamiSettings extends LocalSettings implements Storeable
|
|||
];
|
||||
}
|
||||
|
||||
public function beforeSave(ActionRequest $request): void
|
||||
{
|
||||
NamiLoginCheckAction::run([
|
||||
'mglnr' => $request->mglnr,
|
||||
'password' => $request->password,
|
||||
]);
|
||||
}
|
||||
|
||||
public function localGroup(): ?Group
|
||||
{
|
||||
return Group::firstWhere('nami_id', $this->default_group_id);
|
||||
|
|
|
@ -7,7 +7,7 @@ use Illuminate\View\Component;
|
|||
class Header extends Component
|
||||
{
|
||||
|
||||
public function __construct(public string $title, public bool $closeable = false)
|
||||
public function __construct(public string $title)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -15,17 +15,12 @@ class Header extends Component
|
|||
{
|
||||
return <<<'HTML'
|
||||
<div class="h-16 px-6 flex items-center justify-between border-b border-solid border-gray-600 group-[.is-bright]:border-gray-500">
|
||||
<div class="flex items-center space-x-2">
|
||||
<div class="flex items-center space-x-4">
|
||||
{{ $beforeTitle ?? ''}}
|
||||
<span class="text-sm md:text-xl font-semibold leading-none text-white">{{ $title }}</span>
|
||||
{{ $toolbar ?? '' }}
|
||||
</div>
|
||||
<div class="flex items-center space-x-4 ml-2">
|
||||
@if ($closeable)
|
||||
<a href="#" class="btn label btn-primary-light icon" wire:click="close">
|
||||
<ui-sprite class="w-3 h-3" src="close"></ui-sprite>
|
||||
</a>
|
||||
@endif
|
||||
{{ $right ?? '' }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,8 +7,9 @@ use Illuminate\View\Component;
|
|||
class Layout extends Component
|
||||
{
|
||||
|
||||
public function __construct(public string $pageClass = '')
|
||||
public function __construct(public string $pageClass = '', public string $title = '')
|
||||
{
|
||||
session()->put('title', $title);
|
||||
}
|
||||
|
||||
public function userName(): string
|
||||
|
@ -26,9 +27,9 @@ class Layout extends Component
|
|||
return <<<'HTML'
|
||||
<div class="grow flex flex-col" @refresh-page.window="$wire.$refresh">
|
||||
<div class="grow bg-gray-900 flex flex-col duration-300 navbar:ml-60">
|
||||
<x-page::header title="{{ session()->get('title') }}">
|
||||
<x-page::header :title="$title">
|
||||
<x-slot:beforeTitle>
|
||||
<a href="#" class="mr-2 lg:hidden" wire:click.prevent="dispatch('toggle-sidebar')">
|
||||
<a href="#" class="lg:hidden" wire:click.prevent="dispatch('toggle-sidebar')">
|
||||
<x-ui::sprite src="menu" class="text-gray-100 w-5 h-5"></x-ui::sprite>
|
||||
</a>
|
||||
</x-slot:beforeTitle>
|
||||
|
|
|
@ -18,15 +18,19 @@ class SettingLayout extends Component
|
|||
'is_active' => get_class($setting) === $active,
|
||||
'title' => $setting->title(),
|
||||
])->toArray();
|
||||
session()->put('menu', 'setting');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return <<<'HTML'
|
||||
<x-page::layout>
|
||||
<x-page::layout :title="$active::title()">
|
||||
<x-slot:right>
|
||||
{{ $right ?? '' }}
|
||||
</x-slot:right>
|
||||
<x-slot:toolbar>
|
||||
{{ $toolbar ?? '' }}
|
||||
</x-slot:toolbar>
|
||||
<div class="flex grow relative">
|
||||
<x-ui::menulist :entries="$entries"></x-ui::menulist>
|
||||
<div class="grow">
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Ui;
|
||||
|
||||
use App\View\Traits\HasColors;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Badge extends Component
|
||||
{
|
||||
|
||||
use HasColors;
|
||||
|
||||
public function __construct(
|
||||
public string $icon,
|
||||
public string $variant = 'primary'
|
||||
) {
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return <<<'HTML'
|
||||
<button type="button" href="#" {{ $attributes }} class="h-6 px-3 space-x-2 items-center rounded-full {{ $allColors($variant) }} hidden lg:flex">
|
||||
<x-ui::sprite class="w-3 h-3 flex-none" :src="$icon"></x-ui::sprite>
|
||||
<span class="text-sm">
|
||||
{{$slot}}
|
||||
</span>
|
||||
</button>
|
||||
<button type="button" x-tooltip.raw="{{$slot}}" href="#" {{ $attributes }} class="h-6 px-3 space-x-2 flex items-center rounded-full {{ $allColors($variant) }} lg:hidden">
|
||||
<x-ui::sprite class="w-3 h-3 flex-none" :src="$icon"></x-ui::sprite>
|
||||
</button>
|
||||
HTML;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Ui;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class SettingIntro extends Component
|
||||
{
|
||||
|
||||
public function __construct(public ?string $title = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return <<<'HTML'
|
||||
<div {{$attributes}}>
|
||||
@if ($title) <h2 class="text-lg font-semibold text-gray-300">{{$title}}</h2> @endif
|
||||
<div class="text-gray-100 text-sm">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</div>
|
||||
HTML;
|
||||
}
|
||||
}
|
|
@ -86,7 +86,8 @@
|
|||
"mockery/mockery": "^1.4.4",
|
||||
"orchestra/testbench": "^9.0",
|
||||
"pestphp/pest": "^3.0",
|
||||
"phpstan/phpstan-mockery": "^1.1"
|
||||
"phpstan/phpstan-mockery": "^1.1",
|
||||
"qossmic/deptrac": "^2.0"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
|
@ -121,6 +122,10 @@
|
|||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"scripts": {
|
||||
"archtest": [
|
||||
"./vendor/bin/deptrac analyze",
|
||||
"./vendor/bin/pest tests/Arch.php"
|
||||
],
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "67ae3a3987355f098ee6f850c6f8e846",
|
||||
"content-hash": "3ffa3d4a189ba5d296ca71166298a74f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "amphp/amp",
|
||||
|
@ -15743,6 +15743,51 @@
|
|||
},
|
||||
"time": "2024-09-11T15:47:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "qossmic/deptrac",
|
||||
"version": "2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/qossmic/deptrac.git",
|
||||
"reference": "f646695c1468051138e1347d89590f9084fa6256"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/qossmic/deptrac/zipball/f646695c1468051138e1347d89590f9084fa6256",
|
||||
"reference": "f646695c1468051138e1347d89590f9084fa6256",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "For using the JUnit output formatter"
|
||||
},
|
||||
"bin": [
|
||||
"bin/deptrac",
|
||||
"deptrac.phar"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Qossmic\\Deptrac\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Deptrac is a static code analysis tool that helps to enforce rules for dependencies between software layers.",
|
||||
"support": {
|
||||
"issues": "https://github.com/qossmic/deptrac/issues",
|
||||
"source": "https://github.com/qossmic/deptrac/tree/2.0.1"
|
||||
},
|
||||
"time": "2024-06-17T10:43:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "rector/rector",
|
||||
"version": "1.2.5",
|
||||
|
|
|
@ -182,6 +182,7 @@ return [
|
|||
Modules\Module\ModuleServiceProvider::class,
|
||||
Modules\Invoice\InvoiceServiceProvider::class,
|
||||
Modules\Mailgateway\MailgatewayServiceProvider::class,
|
||||
Modules\Nami\NamiServiceProvider::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
deptrac:
|
||||
paths:
|
||||
- ./app
|
||||
- ./modules
|
||||
exclude_files:
|
||||
- '#.*Test.php$#'
|
||||
layers:
|
||||
- name: AppFiles
|
||||
collectors:
|
||||
- type: bool
|
||||
must:
|
||||
- type: classLike
|
||||
value: .*
|
||||
- type: directory
|
||||
value: app/.*
|
||||
|
||||
- name: ModuleFiles
|
||||
collectors:
|
||||
- type: bool
|
||||
must:
|
||||
- type: classLike
|
||||
value: .*
|
||||
- type: directory
|
||||
value: modules/.*
|
||||
|
||||
ruleset:
|
||||
ModuleFiles:
|
||||
- AppFiles
|
||||
AppFiles:
|
||||
- ModuleFiles
|
|
@ -35,8 +35,9 @@ class SettingView extends Component
|
|||
<form id="billsettingform" class="grow p-6 grid grid-cols-2 gap-3 items-start content-start" wire:submit.prevent="save">
|
||||
<x-form::text name="from" wire:model="settings.from" label="Absender" hint="Absender-Name in Kurzform, i.d.R. der kurze Stammesname"></x-form::text>
|
||||
<x-form::text name="from_long" wire:model="settings.from_long" label="Absender (lang)" hint="Absender-Name in Langform, i.d.R. der Stammesname"></x-form::text>
|
||||
<h2 class="text-lg font-semibold text-gray-300 col-span-2 mt-5">Kontaktdaten</h2>
|
||||
<div class="col-span-2 text-gray-300 text-sm">Diese Kontaktdaten stehen im Absender-Bereich auf der Rechnung.</div>
|
||||
<x-ui::setting-intro class="col-span-full mt-5" title="Kontaktdaten">
|
||||
Hier kannst du deine Zugangsdaten zu NaMi anpassen, falls sich z.B. dein Passwort geändert hat.
|
||||
</x-ui::setting-intro>
|
||||
<x-form::text name="address" wire:model="settings.address" label="Straße"></x-form::text>
|
||||
<x-form::text name="zip" wire:model="settings.zip" label="PLZ"></x-form::text>
|
||||
<x-form::text name="place" wire:model="settings.place" label="Ort"></x-form::text>
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace Modules\Mailgateway\Components;
|
||||
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use Modules\Mailgateway\Models\Mailgateway;
|
||||
use Modules\Mailgateway\Types\Type;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\Attributes\Validate;
|
||||
|
@ -15,9 +15,9 @@ class Form extends Component
|
|||
|
||||
public string $name = '';
|
||||
public string $domain = '';
|
||||
public array $params = [];
|
||||
#[Validate('required')]
|
||||
public ?string $cls = null;
|
||||
public ?Type $type = null;
|
||||
#[Validate('required|string')]
|
||||
public ?string $typeClass = null;
|
||||
public Collection $types;
|
||||
public ?Mailgateway $model = null;
|
||||
|
||||
|
@ -26,19 +26,17 @@ class Form extends Component
|
|||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'domain' => 'required|string|max:255',
|
||||
'cls' => ['required', 'string', 'max:255', Rule::in(app('mail-gateways'))],
|
||||
'params' => 'present|array',
|
||||
...$this->cls ? collect($this->cls::rules())->mapWithKeys(fn ($rules, $key) => ["params.{$key}" => $rules]) : [],
|
||||
...$this->type ? collect($this->type::rules())->mapWithKeys(fn ($rules, $key) => ["type.{$key}" => $rules]) : [],
|
||||
];
|
||||
}
|
||||
|
||||
public function validationAttributes(): array
|
||||
{
|
||||
return [
|
||||
'cls' => 'Typ',
|
||||
'type' => 'Typ',
|
||||
'name' => 'Beschreibung',
|
||||
'domain' => 'Domain',
|
||||
...$this->cls ? collect($this->cls::fieldNames())->mapWithKeys(fn ($attribute, $key) => ["params.{$key}" => $attribute]) : [],
|
||||
...$this->type ? collect($this->type::fieldNames())->mapWithKeys(fn ($attribute, $key) => ["params.{$key}" => $attribute]) : [],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -53,19 +51,23 @@ class Form extends Component
|
|||
$this->model = Mailgateway::find($id);
|
||||
$this->name = $this->model->name;
|
||||
$this->domain = $this->model->domain;
|
||||
$this->cls = get_class($this->model->type);
|
||||
$this->params = (array) $this->model->type;
|
||||
$this->type = $this->model->type;
|
||||
$this->typeClass = get_class($this->model->type);
|
||||
}
|
||||
}
|
||||
|
||||
public function updatedType(string $type): void
|
||||
{
|
||||
$this->params = $type::defaults();
|
||||
}
|
||||
|
||||
public function fields(): array
|
||||
{
|
||||
return $this->cls ? $this->cls::fields() : [];
|
||||
return $this->type ? $this->type::fields() : [];
|
||||
}
|
||||
|
||||
public function updatedTypeClass(?string $type): void
|
||||
{
|
||||
if (!$type) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->type = $type::from([]);
|
||||
}
|
||||
|
||||
#[On('onStoreFromModal')]
|
||||
|
@ -73,14 +75,14 @@ class Form extends Component
|
|||
{
|
||||
$this->validate();
|
||||
|
||||
if (!app($this->cls)->setParams($this->params)->works()) {
|
||||
if (!$this->type->works()) {
|
||||
throw ValidationException::withMessages(['connection' => 'Verbindung fehlgeschlagen.']);
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'name' => $this->name,
|
||||
'domain' => $this->domain,
|
||||
'type' => ['cls' => $this->cls, 'params' => $this->params],
|
||||
'type' => $this->type,
|
||||
];
|
||||
if ($this->model) {
|
||||
$this->model->update($payload);
|
||||
|
@ -99,11 +101,11 @@ class Form extends Component
|
|||
<form class="grid grid-cols-2 gap-3">
|
||||
<x-form::text name="name" wire:model="name" label="Beschreibung" required />
|
||||
<x-form::text name="domain" wire:model="domain" label="Domain" required />
|
||||
<x-form::select name="cls" wire:model.live="cls" label="Typ" :options="$types" required />
|
||||
<x-form::select name="typeClass" wire:model.live="typeClass" label="Typ" :options="$types" required />
|
||||
@foreach($this->fields() as $index => $field)
|
||||
<x-form::text
|
||||
wire:key="index"
|
||||
wire:model="params.{{$field['name']}}"
|
||||
wire:model="type.{{$field['name']}}"
|
||||
:label="$field['label']"
|
||||
:type="$field['type']"
|
||||
:name="$field['name']"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Modules\Mailgateway\Components;
|
||||
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use Modules\Mailgateway\Models\Mailgateway;
|
||||
use Livewire\Component;
|
||||
use Modules\Mailgateway\MailgatewaySettings;
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<x-page::setting-layout :active="$settingClass">
|
||||
<x-slot:toolbar>
|
||||
<x-ui::badge wire:click.prevent="$dispatch('openModal', {component: 'modules.mailgateway.components.form', props: {}, title: 'Verbindung erstellen'})" icon="plus">Neue Verbindung</x-ui::badge>
|
||||
</x-slot:toolbar>
|
||||
<div>
|
||||
<x-ui::table>
|
||||
<thead>
|
||||
|
@ -9,7 +12,6 @@
|
|||
<th>Aktion</th>
|
||||
</thead>
|
||||
|
||||
<x-ui::action wire:click.prevent="$dispatch('openModal', {component: 'modules.mailgateway.components.form', props: {}, title: 'Verbindung erstellen'})" icon="plus" variant="danger">Neu</x-ui::action>
|
||||
|
||||
@foreach ($data as $index => $gateway)
|
||||
<tr wire:key="$index">
|
||||
|
|
|
@ -7,6 +7,8 @@ use Illuminate\Routing\Router;
|
|||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\Mailgateway\Components\SettingView;
|
||||
use Modules\Mailgateway\Types\LocalType;
|
||||
use Modules\Mailgateway\Types\MailmanType;
|
||||
|
||||
class MailgatewayServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
@ -32,6 +34,11 @@ class MailgatewayServiceProvider extends ServiceProvider
|
|||
$router->get('/setting/mailgateway', SettingView::class)->name('setting.mailgateway');
|
||||
});
|
||||
|
||||
app()->bind('mail-gateways', fn () => collect([
|
||||
LocalType::class,
|
||||
MailmanType::class,
|
||||
]));
|
||||
|
||||
View::addNamespace('mailgateway', __DIR__ . '/Components');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mailgateway\Models;
|
||||
namespace Modules\Mailgateway\Models;
|
||||
|
||||
use App\Mailgateway\Casts\TypeCast;
|
||||
use Database\Factories\Mailgateway\Models\MailgatewayFactory;
|
||||
use Modules\Mailgateway\Types\Type;
|
||||
use Illuminate\Database\Eloquent\Concerns\HasUuids;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Mailgateway extends Model
|
||||
{
|
||||
|
||||
public static $factory = MailgatewayFactory::class;
|
||||
|
||||
/** @use HasFactory<MailgatewayFactory> */
|
||||
use HasFactory;
|
||||
use HasUuids;
|
||||
|
||||
public $casts = ['type' => TypeCast::class];
|
||||
public $casts = ['type' => Type::class];
|
||||
public $guarded = [];
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Factories\Mailgateway\Models;
|
||||
namespace Modules\Mailgateway\Models;
|
||||
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use App\Mailgateway\Types\Type;
|
||||
use Modules\Mailgateway\Types\Type;
|
||||
use Modules\Mailgateway\Types\LocalType;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Mailgateway\Models\Mailgateway>
|
||||
* @extends Factory<Mailgateway>
|
||||
*/
|
||||
class MailgatewayFactory extends Factory
|
||||
{
|
||||
|
@ -22,24 +22,14 @@ class MailgatewayFactory extends Factory
|
|||
{
|
||||
return [
|
||||
'name' => $this->faker->words(5, true),
|
||||
'type' => [
|
||||
'cls' => app('mail-gateways')->random(),
|
||||
'params' => [],
|
||||
],
|
||||
'type' => new LocalType(),
|
||||
'domain' => $this->faker->safeEmailDomain(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string<Type> $type
|
||||
* @param array<string, mixed> $params
|
||||
*/
|
||||
public function type(string $type, array $params): self
|
||||
public function type(Type $type): self
|
||||
{
|
||||
return $this->state(['type' => [
|
||||
'cls' => $type,
|
||||
'params' => $params,
|
||||
]]);
|
||||
return $this->state(['type' => $type]);
|
||||
}
|
||||
|
||||
public function name(string $name): self
|
|
@ -1,10 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Mailgateway;
|
||||
namespace Modules\Mailgateway\Tests;
|
||||
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use App\Mailgateway\Types\LocalType;
|
||||
use App\Mailgateway\Types\MailmanType;
|
||||
use Modules\Mailgateway\Models\Mailgateway;
|
||||
use Modules\Mailgateway\Types\LocalType;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Livewire\Livewire;
|
||||
use Modules\Mailgateway\Components\SettingView;
|
||||
|
@ -21,7 +20,7 @@ it('test it can view index page', function () {
|
|||
|
||||
it('test it displays local gateways', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
Mailgateway::factory()->type(LocalType::class, [])->name('Lore')->domain('example.com')->create();
|
||||
Mailgateway::factory()->type(LocalType::from([]))->name('Lore')->domain('example.com')->create();
|
||||
|
||||
Livewire::test(SettingView::class)
|
||||
->assertSeeHtml('example.com')
|
||||
|
@ -32,8 +31,8 @@ it('test it displays local gateways', function () {
|
|||
|
||||
it('displays mailman gateways', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
$typeParams = MailmanTypeRequest::new()->succeeds()->create(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner']);
|
||||
Mailgateway::factory()->type(MailmanType::class, $typeParams)->create();
|
||||
$typeParams = MailmanTypeRequest::new()->succeeds()->state(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner']);
|
||||
Mailgateway::factory()->type($typeParams->toData())->create();
|
||||
|
||||
Livewire::test(SettingView::class)->assertSeeHtml('Verbindung erfolgreich');
|
||||
});
|
|
@ -1,12 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Mailgateway;
|
||||
namespace Modules\Mailgateway\Tests;
|
||||
|
||||
use App\Mailgateway\Types\LocalType;
|
||||
use App\Mailgateway\Types\MailmanType;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Livewire\Livewire;
|
||||
use Modules\Mailgateway\Components\Form;
|
||||
use Modules\Mailgateway\Types\LocalType;
|
||||
use Modules\Mailgateway\Types\MailmanType;
|
||||
use Tests\RequestFactories\MailmanTypeRequest;
|
||||
use Tests\TestCase;
|
||||
|
||||
|
@ -17,39 +17,32 @@ it('test it saves a mail gateway', function () {
|
|||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
|
||||
Livewire::test(Form::class)
|
||||
->set('typeClass', LocalType::class)
|
||||
->set('name', 'lala')
|
||||
->set('domain', 'example.com')
|
||||
->set('cls', LocalType::class)
|
||||
->call('onSave')
|
||||
->assertHasNoErrors()
|
||||
->assertDispatched('closeModal')
|
||||
->assertDispatched('refresh-page')
|
||||
->assertDispatched('success');
|
||||
|
||||
$this->assertDatabaseHas('mailgateways', [
|
||||
test()->assertDatabaseHas('mailgateways', [
|
||||
'domain' => 'example.com',
|
||||
'name' => 'lala',
|
||||
'type' => json_encode([
|
||||
'cls' => LocalType::class,
|
||||
'params' => [],
|
||||
'type' => LocalType::class,
|
||||
'data' => [],
|
||||
]),
|
||||
]);
|
||||
});
|
||||
|
||||
it('validates type', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
|
||||
Livewire::test(Form::class)
|
||||
->set('cls', '')
|
||||
->assertHasErrors(['cls' => 'required']);
|
||||
});
|
||||
|
||||
it('test it validates mail gateway', function (array $attributes, array $errors) {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
|
||||
Livewire::test(Form::class)
|
||||
->set('name', 'lala')
|
||||
->set('domain', 'example.com')
|
||||
->set('cls', LocalType::class)
|
||||
->set('typeClass', LocalType::class)
|
||||
->setArray($attributes)
|
||||
->call('onSave')
|
||||
->assertHasErrors($errors)
|
||||
|
@ -59,6 +52,7 @@ it('test it validates mail gateway', function (array $attributes, array $errors)
|
|||
})->with([
|
||||
[['name' => ''], ['name' => 'required']],
|
||||
[['domain' => ''], ['domain' => 'required']],
|
||||
[['typeClass' => ''], ['typeClass' => 'required']],
|
||||
]);
|
||||
|
||||
it('test it validates mailman type', function (array $attributes, array $errors) {
|
||||
|
@ -67,20 +61,20 @@ it('test it validates mailman type', function (array $attributes, array $errors)
|
|||
Livewire::test(Form::class)
|
||||
->set('name', 'lala')
|
||||
->set('domain', 'example.com')
|
||||
->set('cls', MailmanType::class)
|
||||
->set('params.url', 'exampl.com')
|
||||
->set('params.user', '::user::')
|
||||
->set('params.password', 'password')
|
||||
->set('typeClass', MailmanType::class)
|
||||
->set('type.url', 'exampl.com')
|
||||
->set('type.user', '::user::')
|
||||
->set('type.password', 'password')
|
||||
->setArray($attributes)
|
||||
->call('onSave')
|
||||
->assertHasErrors($errors)
|
||||
->assertNotDispatched('closeModal');
|
||||
})->with([
|
||||
[['params.url' => ''], ['params.url' => 'required']],
|
||||
[['params.user' => ''], ['params.user' => 'required']],
|
||||
[['params.password' => ''], ['params.password' => 'required']],
|
||||
[['params.owner' => ''], ['params.owner' => 'required']],
|
||||
[['params.owner' => 'aaa'], ['params.owner' => 'email']],
|
||||
[['type.url' => ''], ['type.url' => 'required']],
|
||||
[['type.user' => ''], ['type.user' => 'required']],
|
||||
[['type.password' => ''], ['type.password' => 'required']],
|
||||
[['type.owner' => ''], ['type.owner' => 'required']],
|
||||
[['type.owner' => 'aaa'], ['type.owner' => 'email']],
|
||||
]);
|
||||
|
||||
it('test it stores mailman gateway', function () {
|
||||
|
@ -92,16 +86,16 @@ it('test it stores mailman gateway', function () {
|
|||
->setArray([
|
||||
'name' => 'lala',
|
||||
'domain' => 'https://example.com',
|
||||
'cls' => MailmanType::class,
|
||||
'params' => $typeParams
|
||||
'typeClass' => MailmanType::class,
|
||||
])
|
||||
->setArray('type', $typeParams)
|
||||
->call('onSave')
|
||||
->assertDispatched('closeModal');
|
||||
|
||||
$this->assertDatabaseHas('mailgateways', [
|
||||
test()->assertDatabaseHas('mailgateways', [
|
||||
'type' => json_encode([
|
||||
'cls' => MailmanType::class,
|
||||
'params' => $typeParams,
|
||||
'type' => MailmanType::class,
|
||||
'data' => $typeParams,
|
||||
]),
|
||||
'name' => 'lala',
|
||||
'domain' => 'https://example.com',
|
||||
|
@ -117,12 +111,12 @@ it('test it checks mailman connection', function () {
|
|||
->setArray([
|
||||
'name' => 'lala',
|
||||
'domain' => 'https://example.com',
|
||||
'cls' => MailmanType::class,
|
||||
'params' => $typeParams
|
||||
'typeClass' => MailmanType::class,
|
||||
])
|
||||
->setArray('type', $typeParams)
|
||||
->call('onSave')
|
||||
->assertHasErrors('connection')
|
||||
->assertNotDispatched('closeModal');
|
||||
|
||||
$this->assertDatabaseCount('mailgateways', 0);
|
||||
test()->assertDatabaseCount('mailgateways', 0);
|
||||
});
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Mailgateway;
|
||||
namespace Modules\Mailgateway\Tests;
|
||||
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use App\Mailgateway\Types\LocalType;
|
||||
use App\Mailgateway\Types\MailmanType;
|
||||
use Modules\Mailgateway\Models\Mailgateway;
|
||||
use Modules\Mailgateway\Types\LocalType;
|
||||
use Modules\Mailgateway\Types\MailmanType;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Livewire\Livewire;
|
||||
use Modules\Mailgateway\Components\Form;
|
||||
|
@ -17,47 +17,52 @@ uses(TestCase::class);
|
|||
it('test it sets attributes for mailman', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
|
||||
$typeParams = MailmanTypeRequest::new()->create(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner']);
|
||||
$mailgateway = Mailgateway::factory()->type(MailmanType::class, $typeParams)->create(['name' => '::name::', 'domain' => 'example.com']);
|
||||
$typeParams = MailmanTypeRequest::new()->state(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner']);
|
||||
$mailgateway = Mailgateway::factory()->type($typeParams->toData())->create(['name' => '::name::', 'domain' => 'example.com']);
|
||||
|
||||
Livewire::test(Form::class, ['id' => $mailgateway->id])
|
||||
->assertSet('model', fn ($m) => $m->is($mailgateway))
|
||||
->assertSet('name', '::name::')
|
||||
->assertSet('domain', 'example.com')
|
||||
->assertSet('cls', MailmanType::class)
|
||||
->assertSet('params.url', 'https://mailman.example.com')
|
||||
->assertSet('params.user', 'user')
|
||||
->assertSet('params.password', 'password')
|
||||
->assertSet('params.owner', 'owner');
|
||||
->assertSet(
|
||||
'type',
|
||||
fn ($type) => $type instanceof MailmanType
|
||||
&& $type->url === 'https://mailman.example.com'
|
||||
&& $type->user === 'user' &&
|
||||
$type->password === 'password'
|
||||
&& $type->owner === 'owner'
|
||||
);
|
||||
});
|
||||
|
||||
it('test it sets attributes for local', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
|
||||
$mailgateway = Mailgateway::factory()->type(LocalType::class, [])->create(['name' => '::name::', 'domain' => 'example.com']);
|
||||
$mailgateway = Mailgateway::factory()->create(['name' => '::name::', 'domain' => 'example.com']);
|
||||
|
||||
Livewire::test(Form::class, ['id' => $mailgateway->id])
|
||||
->assertSet('name', '::name::')
|
||||
->assertSet('domain', 'example.com')
|
||||
->assertSet('cls', LocalType::class)
|
||||
->assertSet('params', []);
|
||||
->assertSet('type', fn ($type) => $type instanceof LocalType);
|
||||
});
|
||||
|
||||
it('test it validates type', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
|
||||
$mailgateway = Mailgateway::factory()->type(LocalType::class, [])->create(['name' => '::name::', 'domain' => 'example.com']);
|
||||
$mailgateway = Mailgateway::factory()->create(['name' => '::name::', 'domain' => 'example.com']);
|
||||
|
||||
Livewire::test(Form::class, ['id' => $mailgateway->id])
|
||||
->set('cls', '')
|
||||
->assertHasErrors(['cls' => 'required']);
|
||||
->set('typeClass', '')
|
||||
->assertHasErrors(['typeClass' => 'required']);
|
||||
});
|
||||
|
||||
it('test it updates a mailman gateway without updating password', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
|
||||
$typeParams = MailmanTypeRequest::new()->succeeds()->create(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com']);
|
||||
$mailgateway = Mailgateway::factory()->type(MailmanType::class, $typeParams)->create(['name' => '::name::', 'domain' => 'example.com']);
|
||||
$typeParams = MailmanTypeRequest::new()
|
||||
->succeeds()
|
||||
->state(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com'])
|
||||
->toData();
|
||||
$mailgateway = Mailgateway::factory()->type($typeParams)->create(['name' => '::name::', 'domain' => 'example.com']);
|
||||
|
||||
Livewire::test(Form::class, ['id' => $mailgateway->id])
|
||||
->set('name', '::newname::')
|
||||
|
@ -70,37 +75,37 @@ it('test it updates a mailman gateway without updating password', function () {
|
|||
$this->assertDatabaseCount('mailgateways', 1);
|
||||
$this->assertDatabaseHas('mailgateways', [
|
||||
'name' => '::newname::',
|
||||
'type' => json_encode(['cls' => MailmanType::class, 'params' => $typeParams]),
|
||||
'type' => json_encode(['type' => MailmanType::class, 'data' => $typeParams]),
|
||||
]);
|
||||
});
|
||||
|
||||
it('test it updates a mailman gateway with password', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
|
||||
$typeParams = MailmanTypeRequest::new()->create(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com']);
|
||||
$typeParams = MailmanTypeRequest::new()->state(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com']);
|
||||
$newTypeParams = MailmanTypeRequest::new()->succeeds()->create(['url' => 'https://mailman.example.com', 'user' => 'newuser', 'password' => 'password', 'owner' => 'owner@example.com']);
|
||||
$mailgateway = Mailgateway::factory()->type(MailmanType::class, $typeParams)->create();
|
||||
$mailgateway = Mailgateway::factory()->type($typeParams->toData())->create();
|
||||
|
||||
Livewire::test(Form::class, ['id' => $mailgateway->id])
|
||||
->set('params.user', 'newuser')
|
||||
->set('type.user', 'newuser')
|
||||
->call('onSave')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$this->assertDatabaseCount('mailgateways', 1);
|
||||
$this->assertDatabaseHas('mailgateways', [
|
||||
'type' => json_encode(['cls' => MailmanType::class, 'params' => $newTypeParams]),
|
||||
'type' => json_encode(['type' => MailmanType::class, 'data' => $newTypeParams]),
|
||||
]);
|
||||
});
|
||||
|
||||
it('test it checks mailgateway connection when updating', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
|
||||
$typeParams = MailmanTypeRequest::new()->create(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com']);
|
||||
$typeParams = MailmanTypeRequest::new()->state(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com']);
|
||||
MailmanTypeRequest::new()->fails()->create(['url' => 'https://mailman.example.com', 'user' => 'newuser', 'password' => 'password', 'owner' => 'owner@example.com']);
|
||||
$mailgateway = Mailgateway::factory()->type(MailmanType::class, $typeParams)->create();
|
||||
$mailgateway = Mailgateway::factory()->type($typeParams->toData())->create();
|
||||
|
||||
Livewire::test(Form::class, ['id' => $mailgateway->id])
|
||||
->set('params.user', 'newuser')
|
||||
->set('type.user', 'newuser')
|
||||
->call('onSave')
|
||||
->assertHasErrors('connection');
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mailgateway\Types;
|
||||
namespace Modules\Mailgateway\Types;
|
||||
|
||||
use App\Maildispatcher\Data\MailEntry;
|
||||
use App\Maildispatcher\Models\Localmaildispatcher;
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mailgateway\Types;
|
||||
namespace Modules\Mailgateway\Types;
|
||||
|
||||
use App\Maildispatcher\Data\MailEntry;
|
||||
use App\Mailman\Data\MailingList;
|
|
@ -1,12 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mailgateway\Types;
|
||||
namespace Modules\Mailgateway\Types;
|
||||
|
||||
use App\Maildispatcher\Data\MailEntry;
|
||||
use Illuminate\Support\Collection;
|
||||
use Livewire\Wireable;
|
||||
use Spatie\LaravelData\Concerns\WireableData;
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
abstract class Type
|
||||
abstract class Type extends Data implements Wireable
|
||||
{
|
||||
|
||||
use WireableData;
|
||||
|
||||
abstract public static function name(): string;
|
||||
|
||||
/**
|
||||
|
@ -67,17 +73,6 @@ abstract class Type
|
|||
])->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<string, mixed>>
|
||||
*/
|
||||
public function toResource(): array
|
||||
{
|
||||
return [
|
||||
'cls' => get_class($this),
|
||||
'params' => get_object_vars($this),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection<int, MailEntry> $results
|
||||
*/
|
|
@ -43,10 +43,9 @@ class SettingView extends Component
|
|||
</x-slot:right>
|
||||
<form id="modulesettingform" class="grow p-6 grid grid-cols-2 gap-3 items-start content-start"
|
||||
wire:submit.prevent="save">
|
||||
<div class="col-span-full text-gray-100 mb-3">
|
||||
<p class="text-sm">Hier kannst du Funktionen innerhalb von Adrema (Module) aktivieren oder deaktivieren
|
||||
und so den Funktionsumfang auf deine Bedürfnisse anpassen.</p>
|
||||
</div>
|
||||
<x-ui::setting-intro class="col-span-full">
|
||||
Hier kannst du Funktionen innerhalb von Adrema (Module) aktivieren oder deaktivieren und so den Funktionsumfang auf deine Bedürfnisse anpassen.
|
||||
</x-ui::setting-intro>
|
||||
@foreach ($all as $module)
|
||||
<x-form::lever wire:model="modules" hint="lala" :value="$module['id']" name="modules" size="sm" :label="$module['name']"></x-form::lever>
|
||||
@endforeach
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Nami\Components;
|
||||
|
||||
use App\Initialize\Actions\NamiLoginCheckAction;
|
||||
use App\Setting\NamiSettings;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Livewire\Component;
|
||||
use Zoomyboy\LaravelNami\LoginException;
|
||||
|
||||
class SettingView extends Component
|
||||
{
|
||||
|
||||
public $settingClass = NamiSettings::class;
|
||||
public string $password = '';
|
||||
public string $mglnr = '';
|
||||
public string $default_group_id = '';
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'password' => 'required|string',
|
||||
'default_group_id' => 'required',
|
||||
'mglnr' => 'required',
|
||||
];
|
||||
}
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->mglnr = app(NamiSettings::class)->mglnr;
|
||||
$this->default_group_id = app(NamiSettings::class)->default_group_id;
|
||||
}
|
||||
|
||||
public function save(): void
|
||||
{
|
||||
$validated = $this->validate();
|
||||
try {
|
||||
NamiLoginCheckAction::run([
|
||||
'mglnr' => $this->mglnr,
|
||||
'password' => $this->password,
|
||||
]);
|
||||
app(NamiSettings::class)->fill($validated)->save();
|
||||
$this->dispatch('success', 'Einstellungen gespeichert.');
|
||||
} catch (LoginException $e) {
|
||||
throw ValidationException::withMessages([
|
||||
'mglnr' => 'Login fehlgeschlagen.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return <<<'HTML'
|
||||
<x-page::setting-layout :active="$settingClass">
|
||||
<x-slot:right>
|
||||
<x-form::save-button form="namisettingform"></x-form::save-button>
|
||||
</x-slot:right>
|
||||
<form id="namisettingform" class="grow p-6 grid grid-cols-2 gap-3 items-start content-start" wire:submit.prevent="save">
|
||||
<x-ui::setting-intro class="col-span-full">
|
||||
Hier kannst du deine Zugangsdaten zu NaMi anpassen, falls sich z.B. dein Passwort geändert hat.
|
||||
</x-ui::setting-intro>
|
||||
<x-form::text name="mglnr" wire:model="mglnr" label="Mitgliedsnummer"></x-form::text>
|
||||
<x-form::text name="default_group_id" wire:model="default_group_id" label="Standard-Gruppierung"></x-form::text>
|
||||
<x-form::text name="password" wire:model="password" label="Passwort" name="password" type="password"></x-form::text>
|
||||
</form>
|
||||
</x-page::setting-layout>
|
||||
HTML;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Nami;
|
||||
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\Nami\Components\SettingView;
|
||||
|
||||
class NamiServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
app(Router::class)->middleware(['web', 'auth:web'])->group(function ($router) {
|
||||
$router->get('/setting/nami', SettingView::class)->name('setting.nami');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Module;
|
||||
|
||||
use App\Setting\NamiSettings;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Livewire\Livewire;
|
||||
use Modules\Nami\Components\SettingView;
|
||||
use Tests\TestCase;
|
||||
use Zoomyboy\LaravelNami\Authentication\Auth;
|
||||
use Zoomyboy\LaravelNami\Fakes\LoginFake;
|
||||
|
||||
uses(TestCase::class);
|
||||
uses(DatabaseTransactions::class);
|
||||
|
||||
it('it renders page', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
|
||||
test()->get(route('setting.nami'))->assertSeeLivewire(SettingView::class);
|
||||
});
|
||||
|
||||
it('it displays active credentials', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
app(NamiSettings::class)->fill(['mglnr' => 903, 'password' => 'secret', 'default_group_id' => 55])->save();
|
||||
|
||||
Livewire::test(SettingView::class)
|
||||
->assertSet('mglnr', 903)
|
||||
->assertSet('password', '')
|
||||
->assertSet('default_group_id', 55)
|
||||
->assertSee('Mitgliedsnummer')
|
||||
->assertSee('Standard-Gruppierung')
|
||||
->assertSee('Passwort')
|
||||
->assertDontSee('secret');
|
||||
});
|
||||
|
||||
it('it saves credentials', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
Auth::success(100, 'secretneu');
|
||||
app(NamiSettings::class)->fill(['mglnr' => 903, 'password' => 'secret', 'default_group_id' => 55])->save();
|
||||
|
||||
Livewire::test(SettingView::class)
|
||||
->set('mglnr', 100)
|
||||
->set('password', 'secretneu')
|
||||
->set('default_group_id', 80)
|
||||
->call('save')
|
||||
->assertHasNoErrors()
|
||||
->assertDispatched('success', 'Einstellungen gespeichert.');
|
||||
|
||||
$this->assertEquals(100, app(NamiSettings::class)->mglnr);
|
||||
$this->assertEquals('secretneu', app(NamiSettings::class)->password);
|
||||
$this->assertEquals('80', app(NamiSettings::class)->default_group_id);
|
||||
});
|
||||
|
||||
it('validates fields', function ($name, $value, $errors) {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
Auth::success(100, 'secretneu');
|
||||
app(NamiSettings::class)->fill(['mglnr' => 903, 'password' => 'secret', 'default_group_id' => 55])->save();
|
||||
|
||||
Livewire::test(SettingView::class)
|
||||
->set('mglnr', 100)
|
||||
->set('password', 'secretneu')
|
||||
->set('default_group_id', 80)
|
||||
->set($name, $value)
|
||||
->call('save')
|
||||
->assertHasErrors($errors)
|
||||
->assertNotDispatched('success');
|
||||
})->with([
|
||||
['password', '', ['password' => 'required']],
|
||||
['mglnr', '', ['mglnr' => 'required']],
|
||||
['default_group_id', '', ['default_group_id' => 'required']],
|
||||
['default_group_id', null, ['default_group_id' => 'required']],
|
||||
]);
|
||||
|
||||
it('it throws error when saving failed', function () {
|
||||
test()->withoutExceptionHandling()->login()->loginNami();
|
||||
app(NamiSettings::class)->fill(['mglnr' => 903, 'password' => 'secret', 'default_group_id' => 55])->save();
|
||||
|
||||
Livewire::test(SettingView::class)
|
||||
->set('mglnr', 100)
|
||||
->set('password', 'secretneu')
|
||||
->set('default_group_id', 80)
|
||||
->call('save')
|
||||
->assertHasErrors(['mglnr' => 'Login fehlgeschlagen.'])
|
||||
->assertNotDispatched('success');
|
||||
|
||||
$settings = app(NamiSettings::class)->refresh();
|
||||
$this->assertEquals(903, $settings->mglnr);
|
||||
$this->assertEquals('secret', $settings->password);
|
||||
$this->assertEquals('55', $settings->default_group_id);
|
||||
});
|
|
@ -1,47 +0,0 @@
|
|||
<template>
|
||||
<page-layout>
|
||||
<template #right>
|
||||
<f-save-button form="namisettingform"></f-save-button>
|
||||
</template>
|
||||
<setting-layout>
|
||||
<form id="namisettingform" class="grow p-6 grid grid-cols-2 gap-3 items-start content-start" @submit.prevent="submit">
|
||||
<div class="col-span-full text-gray-100 mb-3">
|
||||
<p class="text-sm">Hier kannst du deine Zugangsdaten zu NaMi anpassen, falls sich z.B. dein Passwort geändert hat.</p>
|
||||
</div>
|
||||
<f-text id="mglnr" v-model="inner.mglnr" label="Mitgliedsnummer"></f-text>
|
||||
<f-text id="default_group_id" v-model="inner.default_group_id" label="Standard-Gruppierung"></f-text>
|
||||
<f-text id="password" v-model="inner.password" label="Passwort" name="password" type="password"></f-text>
|
||||
</form>
|
||||
</setting-layout>
|
||||
</page-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SettingLayout from './Layout.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SettingLayout,
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
inner: {...this.data},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.post('/setting/nami', this.inner, {
|
||||
onSuccess: () => this.$success('Einstellungen gespeichert.'),
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||
|
||||
<title>{{ $title ?? 'Page Title' }}</title>
|
||||
<title>{{ session()->get('title') }} | {{ config('app.name') }}</title>
|
||||
<meta name="socketport" content="{{env('SOCKET_PORT')}}" />
|
||||
<meta name="adrema_base_url" content="/">
|
||||
@if(auth()->id())
|
||||
|
|
|
@ -61,8 +61,6 @@ 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;
|
||||
use App\Member\Actions\MemberDeleteAction;
|
||||
use App\Member\Actions\MemberResyncAction;
|
||||
|
@ -112,8 +110,6 @@ Route::group(['middleware' => 'auth:web'], function (): void {
|
|||
Route::post('/contribution-validate', ContributionValidateAction::class)->name('contribution.validate');
|
||||
|
||||
// ----------------------------------- mail ------------------------------------
|
||||
Route::post('/api/mailgateway', StoreAction::class)->name('mailgateway.store');
|
||||
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');
|
||||
|
|
|
@ -2,14 +2,10 @@
|
|||
|
||||
arch()
|
||||
->expect('App')
|
||||
->not->toUse(['die', 'dd', 'dump']);
|
||||
|
||||
->not->toUse(['die', 'dd', 'dump'])
|
||||
->not->toHaveFileSystemPermissions('0777');
|
||||
|
||||
arch()
|
||||
->expect(globArch('App\*\Models'))
|
||||
->toExtend('Illuminate\Database\Eloquent\Model')
|
||||
->toBeClasses();
|
||||
|
||||
arch('app')
|
||||
->expect('App')
|
||||
->expect('Modules')
|
||||
->not->toUse(['die', 'dd', 'dump'])
|
||||
->not->toHaveFileSystemPermissions('0777');
|
||||
|
|
|
@ -6,8 +6,8 @@ use \Mockery as M;
|
|||
use App\Activity;
|
||||
use App\Maildispatcher\Models\Localmaildispatcher;
|
||||
use App\Maildispatcher\Models\Maildispatcher;
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use App\Mailgateway\Types\LocalType;
|
||||
use Modules\Mailgateway\Models\Mailgateway;
|
||||
use Modules\Mailgateway\Types\LocalType;
|
||||
use App\Member\Member;
|
||||
use App\Member\Membership;
|
||||
use Tests\EndToEndTestCase;
|
||||
|
|
|
@ -4,11 +4,10 @@ namespace Tests\EndToEnd\Maildispatcher;
|
|||
|
||||
use App\Maildispatcher\Actions\ResyncAction;
|
||||
use App\Maildispatcher\Models\Maildispatcher;
|
||||
use App\Mailgateway\Models\Mailgateway;
|
||||
use App\Mailgateway\Types\LocalType;
|
||||
use Modules\Mailgateway\Models\Mailgateway;
|
||||
use Modules\Mailgateway\Types\LocalType;
|
||||
use App\Member\FilterScope;
|
||||
use App\Member\Member;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
use Tests\EndToEndTestCase;
|
||||
|
||||
class UpdateTest extends EndToEndTestCase
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Tests\RequestFactories;
|
|||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Worksome\RequestFactories\RequestFactory;
|
||||
use Modules\Mailgateway\Types\MailmanType;
|
||||
|
||||
class MailmanTypeRequest extends RequestFactory
|
||||
{
|
||||
|
@ -49,4 +50,9 @@ class MailmanTypeRequest extends RequestFactory
|
|||
: Http::response([], 401);
|
||||
});
|
||||
}
|
||||
|
||||
public function toData(): MailmanType
|
||||
{
|
||||
return MailmanType::from($this->create());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,10 +174,17 @@ class TestCase extends BaseTestCase
|
|||
return $this;
|
||||
});
|
||||
|
||||
Testable::macro('setArray', function ($attributes) {
|
||||
Testable::macro('setArray', function ($attributes, $value = null) {
|
||||
$self = $this;
|
||||
foreach ($attributes as $key => $value) {
|
||||
$self = $this->set($key, $value);
|
||||
if ($value === null) {
|
||||
foreach ($attributes as $key => $value) {
|
||||
$self = $this->set($key, $value);
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
foreach ($value as $key => $v) {
|
||||
$self = $self->set($attributes . '.' . $key, $v);
|
||||
}
|
||||
|
||||
return $self;
|
||||
|
|
Loading…
Reference in New Issue