Compare commits

..

1 Commits

Author SHA1 Message Date
philipp lang af848e51c6 --wip-- [skip ci] 2024-10-23 21:02:42 +02:00
43 changed files with 399 additions and 459 deletions

View File

@ -2,7 +2,7 @@
namespace App\Maildispatcher\Models; namespace App\Maildispatcher\Models;
use Modules\Mailgateway\Models\Mailgateway; use App\Mailgateway\Models\Mailgateway;
use Database\Factories\Maildispatcher\Models\MaildispatcherFactory; use Database\Factories\Maildispatcher\Models\MaildispatcherFactory;
use Illuminate\Database\Eloquent\Concerns\HasUuids; use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;

View File

@ -4,7 +4,8 @@ namespace App\Maildispatcher\Resources;
use App\Lib\HasMeta; use App\Lib\HasMeta;
use App\Maildispatcher\Models\Maildispatcher; use App\Maildispatcher\Models\Maildispatcher;
use Modules\Mailgateway\Models\Mailgateway; use App\Mailgateway\Models\Mailgateway;
use App\Mailgateway\Resources\MailgatewayResource;
use App\Member\FilterScope; use App\Member\FilterScope;
use App\Member\Member; use App\Member\Member;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;

View File

@ -0,0 +1,27 @@
<?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());
}
}

View File

@ -0,0 +1,28 @@
<?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());
}
}

View File

@ -0,0 +1,65 @@
<?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.']);
}
}
}

View File

@ -0,0 +1,33 @@
<?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)),
];
}
}

View File

@ -1,21 +1,20 @@
<?php <?php
namespace Modules\Mailgateway\Models; namespace App\Mailgateway\Models;
use Modules\Mailgateway\Types\Type; use App\Mailgateway\Types\Type as TypesType;
use Database\Factories\Mailgateway\Models\MailgatewayFactory;
use Illuminate\Database\Eloquent\Concerns\HasUuids; use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Nette\Utils\Type;
class Mailgateway extends Model class Mailgateway extends Model
{ {
public static $factory = MailgatewayFactory::class;
/** @use HasFactory<MailgatewayFactory> */ /** @use HasFactory<MailgatewayFactory> */
use HasFactory; use HasFactory;
use HasUuids; use HasUuids;
public $casts = ['type' => Type::class]; public $casts = ['type' => TypesType::class];
public $guarded = []; public $guarded = [];
} }

View File

@ -0,0 +1,68 @@
<?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(),
'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,
],
],
];
}
}

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Modules\Mailgateway\Types; namespace App\Mailgateway\Types;
use App\Maildispatcher\Data\MailEntry; use App\Maildispatcher\Data\MailEntry;
use App\Maildispatcher\Models\Localmaildispatcher; use App\Maildispatcher\Models\Localmaildispatcher;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Modules\Mailgateway\Types; namespace App\Mailgateway\Types;
use App\Maildispatcher\Data\MailEntry; use App\Maildispatcher\Data\MailEntry;
use App\Mailman\Data\MailingList; use App\Mailman\Data\MailingList;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Modules\Mailgateway\Types; namespace App\Mailgateway\Types;
use App\Maildispatcher\Data\MailEntry; use App\Maildispatcher\Data\MailEntry;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;

View File

@ -3,10 +3,13 @@
namespace App\Providers; namespace App\Providers;
use App\Form\Models\Form; use App\Form\Models\Form;
use App\Mailgateway\Types\LocalType;
use App\Mailgateway\Types\MailmanType;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Laravel\Telescope\Telescope;
class AppServiceProvider extends ServiceProvider class AppServiceProvider extends ServiceProvider
{ {
@ -27,6 +30,11 @@ class AppServiceProvider extends ServiceProvider
return $this; return $this;
}); });
app()->bind('mail-gateways', fn () => collect([
LocalType::class,
MailmanType::class,
]));
app()->extend('media-library-helpers', fn ($p) => $p->put('form', Form::class)); app()->extend('media-library-helpers', fn ($p) => $p->put('form', Form::class));
Blade::componentNamespace('App\\View\\Mail', 'mail-view'); Blade::componentNamespace('App\\View\\Mail', 'mail-view');

View File

@ -3,10 +3,14 @@
namespace App\Setting; namespace App\Setting;
use App\Group; 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\Api;
use Zoomyboy\LaravelNami\Nami; use Zoomyboy\LaravelNami\Nami;
class NamiSettings extends LocalSettings class NamiSettings extends LocalSettings implements Storeable
{ {
public int $mglnr; public int $mglnr;
@ -39,6 +43,14 @@ class NamiSettings extends LocalSettings
]; ];
} }
public function beforeSave(ActionRequest $request): void
{
NamiLoginCheckAction::run([
'mglnr' => $request->mglnr,
'password' => $request->password,
]);
}
public function localGroup(): ?Group public function localGroup(): ?Group
{ {
return Group::firstWhere('nami_id', $this->default_group_id); return Group::firstWhere('nami_id', $this->default_group_id);

View File

@ -7,7 +7,7 @@ use Illuminate\View\Component;
class Header extends Component class Header extends Component
{ {
public function __construct(public string $title) public function __construct(public string $title, public bool $closeable = false)
{ {
} }
@ -15,12 +15,17 @@ class Header extends Component
{ {
return <<<'HTML' 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="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-4"> <div class="flex items-center space-x-2">
{{ $beforeTitle ?? ''}} {{ $beforeTitle ?? ''}}
<span class="text-sm md:text-xl font-semibold leading-none text-white">{{ $title }}</span> <span class="text-sm md:text-xl font-semibold leading-none text-white">{{ $title }}</span>
{{ $toolbar ?? '' }} {{ $toolbar ?? '' }}
</div> </div>
<div class="flex items-center space-x-4 ml-2"> <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 ?? '' }} {{ $right ?? '' }}
</div> </div>
</div> </div>

View File

@ -7,9 +7,8 @@ use Illuminate\View\Component;
class Layout extends Component class Layout extends Component
{ {
public function __construct(public string $pageClass = '', public string $title = '') public function __construct(public string $pageClass = '')
{ {
session()->put('title', $title);
} }
public function userName(): string public function userName(): string
@ -27,9 +26,9 @@ class Layout extends Component
return <<<'HTML' return <<<'HTML'
<div class="grow flex flex-col" @refresh-page.window="$wire.$refresh"> <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"> <div class="grow bg-gray-900 flex flex-col duration-300 navbar:ml-60">
<x-page::header :title="$title"> <x-page::header title="{{ session()->get('title') }}">
<x-slot:beforeTitle> <x-slot:beforeTitle>
<a href="#" class="lg:hidden" wire:click.prevent="dispatch('toggle-sidebar')"> <a href="#" class="mr-2 lg:hidden" wire:click.prevent="dispatch('toggle-sidebar')">
<x-ui::sprite src="menu" class="text-gray-100 w-5 h-5"></x-ui::sprite> <x-ui::sprite src="menu" class="text-gray-100 w-5 h-5"></x-ui::sprite>
</a> </a>
</x-slot:beforeTitle> </x-slot:beforeTitle>

View File

@ -18,19 +18,15 @@ class SettingLayout extends Component
'is_active' => get_class($setting) === $active, 'is_active' => get_class($setting) === $active,
'title' => $setting->title(), 'title' => $setting->title(),
])->toArray(); ])->toArray();
session()->put('menu', 'setting');
} }
public function render() public function render()
{ {
return <<<'HTML' return <<<'HTML'
<x-page::layout :title="$active::title()"> <x-page::layout>
<x-slot:right> <x-slot:right>
{{ $right ?? '' }} {{ $right ?? '' }}
</x-slot:right> </x-slot:right>
<x-slot:toolbar>
{{ $toolbar ?? '' }}
</x-slot:toolbar>
<div class="flex grow relative"> <div class="flex grow relative">
<x-ui::menulist :entries="$entries"></x-ui::menulist> <x-ui::menulist :entries="$entries"></x-ui::menulist>
<div class="grow"> <div class="grow">

View File

@ -1,33 +0,0 @@
<?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;
}
}

View File

@ -1,25 +0,0 @@
<?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;
}
}

View File

@ -86,8 +86,7 @@
"mockery/mockery": "^1.4.4", "mockery/mockery": "^1.4.4",
"orchestra/testbench": "^9.0", "orchestra/testbench": "^9.0",
"pestphp/pest": "^3.0", "pestphp/pest": "^3.0",
"phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-mockery": "^1.1"
"qossmic/deptrac": "^2.0"
}, },
"config": { "config": {
"optimize-autoloader": true, "optimize-autoloader": true,
@ -122,10 +121,6 @@
"minimum-stability": "dev", "minimum-stability": "dev",
"prefer-stable": true, "prefer-stable": true,
"scripts": { "scripts": {
"archtest": [
"./vendor/bin/deptrac analyze",
"./vendor/bin/pest tests/Arch.php"
],
"post-autoload-dump": [ "post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi" "@php artisan package:discover --ansi"

47
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "3ffa3d4a189ba5d296ca71166298a74f", "content-hash": "67ae3a3987355f098ee6f850c6f8e846",
"packages": [ "packages": [
{ {
"name": "amphp/amp", "name": "amphp/amp",
@ -15743,51 +15743,6 @@
}, },
"time": "2024-09-11T15:47:29+00:00" "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", "name": "rector/rector",
"version": "1.2.5", "version": "1.2.5",

View File

@ -182,7 +182,6 @@ return [
Modules\Module\ModuleServiceProvider::class, Modules\Module\ModuleServiceProvider::class,
Modules\Invoice\InvoiceServiceProvider::class, Modules\Invoice\InvoiceServiceProvider::class,
Modules\Mailgateway\MailgatewayServiceProvider::class, Modules\Mailgateway\MailgatewayServiceProvider::class,
Modules\Nami\NamiServiceProvider::class,
], ],
/* /*

View File

@ -1,13 +1,14 @@
<?php <?php
namespace Modules\Mailgateway\Models; namespace Database\Factories\Mailgateway\Models;
use Modules\Mailgateway\Types\Type; use App\Mailgateway\Models\Mailgateway;
use Modules\Mailgateway\Types\LocalType; use App\Mailgateway\Types\LocalType;
use App\Mailgateway\Types\Type;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
/** /**
* @extends Factory<Mailgateway> * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Mailgateway\Models\Mailgateway>
*/ */
class MailgatewayFactory extends Factory class MailgatewayFactory extends Factory
{ {

View File

@ -1,30 +0,0 @@
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

View File

@ -35,9 +35,8 @@ 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"> <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" 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> <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>
<x-ui::setting-intro class="col-span-full mt-5" title="Kontaktdaten"> <h2 class="text-lg font-semibold text-gray-300 col-span-2 mt-5">Kontaktdaten</h2>
Hier kannst du deine Zugangsdaten zu NaMi anpassen, falls sich z.B. dein Passwort geändert hat. <div class="col-span-2 text-gray-300 text-sm">Diese Kontaktdaten stehen im Absender-Bereich auf der Rechnung.</div>
</x-ui::setting-intro>
<x-form::text name="address" wire:model="settings.address" label="Straße"></x-form::text> <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="zip" wire:model="settings.zip" label="PLZ"></x-form::text>
<x-form::text name="place" wire:model="settings.place" label="Ort"></x-form::text> <x-form::text name="place" wire:model="settings.place" label="Ort"></x-form::text>

View File

@ -2,9 +2,10 @@
namespace Modules\Mailgateway\Components; namespace Modules\Mailgateway\Components;
use Modules\Mailgateway\Models\Mailgateway; use App\Mailgateway\Models\Mailgateway;
use Modules\Mailgateway\Types\Type; use App\Mailgateway\Types\Type;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use Livewire\Attributes\On; use Livewire\Attributes\On;
use Livewire\Attributes\Validate; use Livewire\Attributes\Validate;
@ -16,8 +17,6 @@ class Form extends Component
public string $name = ''; public string $name = '';
public string $domain = ''; public string $domain = '';
public ?Type $type = null; public ?Type $type = null;
#[Validate('required|string')]
public ?string $typeClass = null;
public Collection $types; public Collection $types;
public ?Mailgateway $model = null; public ?Mailgateway $model = null;
@ -26,7 +25,7 @@ class Form extends Component
return [ return [
'name' => 'required|string|max:255', 'name' => 'required|string|max:255',
'domain' => 'required|string|max:255', 'domain' => 'required|string|max:255',
...$this->type ? collect($this->type::rules())->mapWithKeys(fn ($rules, $key) => ["type.{$key}" => $rules]) : [], ...$this->type ? collect($this->type::rules())->mapWithKeys(fn ($rules, $key) => ["params.{$key}" => $rules]) : [],
]; ];
} }
@ -52,7 +51,6 @@ class Form extends Component
$this->name = $this->model->name; $this->name = $this->model->name;
$this->domain = $this->model->domain; $this->domain = $this->model->domain;
$this->type = $this->model->type; $this->type = $this->model->type;
$this->typeClass = get_class($this->model->type);
} }
} }
@ -61,15 +59,6 @@ class Form extends Component
return $this->type ? $this->type::fields() : []; return $this->type ? $this->type::fields() : [];
} }
public function updatedTypeClass(?string $type): void
{
if (!$type) {
return;
}
$this->type = $type::from([]);
}
#[On('onStoreFromModal')] #[On('onStoreFromModal')]
public function onSave(): void public function onSave(): void
{ {
@ -101,11 +90,11 @@ class Form extends Component
<form class="grid grid-cols-2 gap-3"> <form class="grid grid-cols-2 gap-3">
<x-form::text name="name" wire:model="name" label="Beschreibung" required /> <x-form::text name="name" wire:model="name" label="Beschreibung" required />
<x-form::text name="domain" wire:model="domain" label="Domain" required /> <x-form::text name="domain" wire:model="domain" label="Domain" required />
<x-form::select name="typeClass" wire:model.live="typeClass" label="Typ" :options="$types" required /> <x-form::select name="type" wire:model.live="type" label="Typ" :options="$types" required />
@foreach($this->fields() as $index => $field) @foreach($this->fields() as $index => $field)
<x-form::text <x-form::text
wire:key="index" wire:key="index"
wire:model="type.{{$field['name']}}" wire:model="$type->{$field['name']}"
:label="$field['label']" :label="$field['label']"
:type="$field['type']" :type="$field['type']"
:name="$field['name']" :name="$field['name']"

View File

@ -2,7 +2,7 @@
namespace Modules\Mailgateway\Components; namespace Modules\Mailgateway\Components;
use Modules\Mailgateway\Models\Mailgateway; use App\Mailgateway\Models\Mailgateway;
use Livewire\Component; use Livewire\Component;
use Modules\Mailgateway\MailgatewaySettings; use Modules\Mailgateway\MailgatewaySettings;

View File

@ -1,7 +1,4 @@
<x-page::setting-layout :active="$settingClass"> <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> <div>
<x-ui::table> <x-ui::table>
<thead> <thead>
@ -12,6 +9,7 @@
<th>Aktion</th> <th>Aktion</th>
</thead> </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) @foreach ($data as $index => $gateway)
<tr wire:key="$index"> <tr wire:key="$index">

View File

@ -1,9 +1,9 @@
<?php <?php
namespace Modules\Mailgateway\Tests; namespace Tests\Feature\Mailgateway;
use Modules\Mailgateway\Models\Mailgateway; use App\Mailgateway\Models\Mailgateway;
use Modules\Mailgateway\Types\LocalType; use App\Mailgateway\Types\LocalType;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Livewire\Livewire; use Livewire\Livewire;
use Modules\Mailgateway\Components\SettingView; use Modules\Mailgateway\Components\SettingView;

View File

@ -7,8 +7,6 @@ use Illuminate\Routing\Router;
use Illuminate\Support\Facades\View; use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Modules\Mailgateway\Components\SettingView; use Modules\Mailgateway\Components\SettingView;
use Modules\Mailgateway\Types\LocalType;
use Modules\Mailgateway\Types\MailmanType;
class MailgatewayServiceProvider extends ServiceProvider class MailgatewayServiceProvider extends ServiceProvider
{ {
@ -34,11 +32,6 @@ class MailgatewayServiceProvider extends ServiceProvider
$router->get('/setting/mailgateway', SettingView::class)->name('setting.mailgateway'); $router->get('/setting/mailgateway', SettingView::class)->name('setting.mailgateway');
}); });
app()->bind('mail-gateways', fn () => collect([
LocalType::class,
MailmanType::class,
]));
View::addNamespace('mailgateway', __DIR__ . '/Components'); View::addNamespace('mailgateway', __DIR__ . '/Components');
} }
} }

View File

@ -1,12 +1,12 @@
<?php <?php
namespace Modules\Mailgateway\Tests; namespace Tests\Feature\Mailgateway;
use App\Mailgateway\Types\LocalType;
use App\Mailgateway\Types\MailmanType;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Livewire\Livewire; use Livewire\Livewire;
use Modules\Mailgateway\Components\Form; use Modules\Mailgateway\Components\Form;
use Modules\Mailgateway\Types\LocalType;
use Modules\Mailgateway\Types\MailmanType;
use Tests\RequestFactories\MailmanTypeRequest; use Tests\RequestFactories\MailmanTypeRequest;
use Tests\TestCase; use Tests\TestCase;
@ -17,16 +17,16 @@ it('test it saves a mail gateway', function () {
test()->withoutExceptionHandling()->login()->loginNami(); test()->withoutExceptionHandling()->login()->loginNami();
Livewire::test(Form::class) Livewire::test(Form::class)
->set('typeClass', LocalType::class)
->set('name', 'lala') ->set('name', 'lala')
->set('domain', 'example.com') ->set('domain', 'example.com')
->set('type', new LocalType())
->call('onSave') ->call('onSave')
->assertHasNoErrors() ->assertHasNoErrors()
->assertDispatched('closeModal') ->assertDispatched('closeModal')
->assertDispatched('refresh-page') ->assertDispatched('refresh-page')
->assertDispatched('success'); ->assertDispatched('success');
test()->assertDatabaseHas('mailgateways', [ $this->assertDatabaseHas('mailgateways', [
'domain' => 'example.com', 'domain' => 'example.com',
'name' => 'lala', 'name' => 'lala',
'type' => json_encode([ 'type' => json_encode([
@ -42,7 +42,7 @@ it('test it validates mail gateway', function (array $attributes, array $errors)
Livewire::test(Form::class) Livewire::test(Form::class)
->set('name', 'lala') ->set('name', 'lala')
->set('domain', 'example.com') ->set('domain', 'example.com')
->set('typeClass', LocalType::class) ->set('type', new LocalType())
->setArray($attributes) ->setArray($attributes)
->call('onSave') ->call('onSave')
->assertHasErrors($errors) ->assertHasErrors($errors)
@ -52,7 +52,7 @@ it('test it validates mail gateway', function (array $attributes, array $errors)
})->with([ })->with([
[['name' => ''], ['name' => 'required']], [['name' => ''], ['name' => 'required']],
[['domain' => ''], ['domain' => 'required']], [['domain' => ''], ['domain' => 'required']],
[['typeClass' => ''], ['typeClass' => 'required']], [['type' => ''], ['type' => 'required']],
]); ]);
it('test it validates mailman type', function (array $attributes, array $errors) { it('test it validates mailman type', function (array $attributes, array $errors) {
@ -61,20 +61,20 @@ it('test it validates mailman type', function (array $attributes, array $errors)
Livewire::test(Form::class) Livewire::test(Form::class)
->set('name', 'lala') ->set('name', 'lala')
->set('domain', 'example.com') ->set('domain', 'example.com')
->set('typeClass', MailmanType::class) ->set('cls', MailmanType::class)
->set('type.url', 'exampl.com') ->set('params.url', 'exampl.com')
->set('type.user', '::user::') ->set('params.user', '::user::')
->set('type.password', 'password') ->set('params.password', 'password')
->setArray($attributes) ->setArray($attributes)
->call('onSave') ->call('onSave')
->assertHasErrors($errors) ->assertHasErrors($errors)
->assertNotDispatched('closeModal'); ->assertNotDispatched('closeModal');
})->with([ })->with([
[['type.url' => ''], ['type.url' => 'required']], [['params.url' => ''], ['params.url' => 'required']],
[['type.user' => ''], ['type.user' => 'required']], [['params.user' => ''], ['params.user' => 'required']],
[['type.password' => ''], ['type.password' => 'required']], [['params.password' => ''], ['params.password' => 'required']],
[['type.owner' => ''], ['type.owner' => 'required']], [['params.owner' => ''], ['params.owner' => 'required']],
[['type.owner' => 'aaa'], ['type.owner' => 'email']], [['params.owner' => 'aaa'], ['params.owner' => 'email']],
]); ]);
it('test it stores mailman gateway', function () { it('test it stores mailman gateway', function () {
@ -86,16 +86,16 @@ it('test it stores mailman gateway', function () {
->setArray([ ->setArray([
'name' => 'lala', 'name' => 'lala',
'domain' => 'https://example.com', 'domain' => 'https://example.com',
'typeClass' => MailmanType::class, 'cls' => MailmanType::class,
'params' => $typeParams
]) ])
->setArray('type', $typeParams)
->call('onSave') ->call('onSave')
->assertDispatched('closeModal'); ->assertDispatched('closeModal');
test()->assertDatabaseHas('mailgateways', [ $this->assertDatabaseHas('mailgateways', [
'type' => json_encode([ 'type' => json_encode([
'type' => MailmanType::class, 'cls' => MailmanType::class,
'data' => $typeParams, 'params' => $typeParams,
]), ]),
'name' => 'lala', 'name' => 'lala',
'domain' => 'https://example.com', 'domain' => 'https://example.com',
@ -111,12 +111,12 @@ it('test it checks mailman connection', function () {
->setArray([ ->setArray([
'name' => 'lala', 'name' => 'lala',
'domain' => 'https://example.com', 'domain' => 'https://example.com',
'typeClass' => MailmanType::class, 'cls' => MailmanType::class,
'params' => $typeParams
]) ])
->setArray('type', $typeParams)
->call('onSave') ->call('onSave')
->assertHasErrors('connection') ->assertHasErrors('connection')
->assertNotDispatched('closeModal'); ->assertNotDispatched('closeModal');
test()->assertDatabaseCount('mailgateways', 0); $this->assertDatabaseCount('mailgateways', 0);
}); });

View File

@ -1,10 +1,10 @@
<?php <?php
namespace Modules\Mailgateway\Tests; namespace Tests\Feature\Mailgateway;
use Modules\Mailgateway\Models\Mailgateway; use App\Mailgateway\Models\Mailgateway;
use Modules\Mailgateway\Types\LocalType; use App\Mailgateway\Types\LocalType;
use Modules\Mailgateway\Types\MailmanType; use App\Mailgateway\Types\MailmanType;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Livewire\Livewire; use Livewire\Livewire;
use Modules\Mailgateway\Components\Form; use Modules\Mailgateway\Components\Form;
@ -48,21 +48,18 @@ it('test it sets attributes for local', function () {
it('test it validates type', function () { it('test it validates type', function () {
test()->withoutExceptionHandling()->login()->loginNami(); test()->withoutExceptionHandling()->login()->loginNami();
$mailgateway = Mailgateway::factory()->create(['name' => '::name::', 'domain' => 'example.com']); $mailgateway = Mailgateway::factory()->type(LocalType::class, [])->create(['name' => '::name::', 'domain' => 'example.com']);
Livewire::test(Form::class, ['id' => $mailgateway->id]) Livewire::test(Form::class, ['id' => $mailgateway->id])
->set('typeClass', '') ->set('cls', '')
->assertHasErrors(['typeClass' => 'required']); ->assertHasErrors(['cls' => 'required']);
}); });
it('test it updates a mailman gateway without updating password', function () { it('test it updates a mailman gateway without updating password', function () {
test()->withoutExceptionHandling()->login()->loginNami(); test()->withoutExceptionHandling()->login()->loginNami();
$typeParams = MailmanTypeRequest::new() $typeParams = MailmanTypeRequest::new()->succeeds()->create(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com']);
->succeeds() $mailgateway = Mailgateway::factory()->type(MailmanType::class, $typeParams)->create(['name' => '::name::', 'domain' => 'example.com']);
->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]) Livewire::test(Form::class, ['id' => $mailgateway->id])
->set('name', '::newname::') ->set('name', '::newname::')
@ -75,37 +72,37 @@ it('test it updates a mailman gateway without updating password', function () {
$this->assertDatabaseCount('mailgateways', 1); $this->assertDatabaseCount('mailgateways', 1);
$this->assertDatabaseHas('mailgateways', [ $this->assertDatabaseHas('mailgateways', [
'name' => '::newname::', 'name' => '::newname::',
'type' => json_encode(['type' => MailmanType::class, 'data' => $typeParams]), 'type' => json_encode(['cls' => MailmanType::class, 'params' => $typeParams]),
]); ]);
}); });
it('test it updates a mailman gateway with password', function () { it('test it updates a mailman gateway with password', function () {
test()->withoutExceptionHandling()->login()->loginNami(); test()->withoutExceptionHandling()->login()->loginNami();
$typeParams = MailmanTypeRequest::new()->state(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com']); $typeParams = MailmanTypeRequest::new()->create(['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']); $newTypeParams = MailmanTypeRequest::new()->succeeds()->create(['url' => 'https://mailman.example.com', 'user' => 'newuser', 'password' => 'password', 'owner' => 'owner@example.com']);
$mailgateway = Mailgateway::factory()->type($typeParams->toData())->create(); $mailgateway = Mailgateway::factory()->type(MailmanType::class, $typeParams)->create();
Livewire::test(Form::class, ['id' => $mailgateway->id]) Livewire::test(Form::class, ['id' => $mailgateway->id])
->set('type.user', 'newuser') ->set('params.user', 'newuser')
->call('onSave') ->call('onSave')
->assertHasNoErrors(); ->assertHasNoErrors();
$this->assertDatabaseCount('mailgateways', 1); $this->assertDatabaseCount('mailgateways', 1);
$this->assertDatabaseHas('mailgateways', [ $this->assertDatabaseHas('mailgateways', [
'type' => json_encode(['type' => MailmanType::class, 'data' => $newTypeParams]), 'type' => json_encode(['cls' => MailmanType::class, 'params' => $newTypeParams]),
]); ]);
}); });
it('test it checks mailgateway connection when updating', function () { it('test it checks mailgateway connection when updating', function () {
test()->withoutExceptionHandling()->login()->loginNami(); test()->withoutExceptionHandling()->login()->loginNami();
$typeParams = MailmanTypeRequest::new()->state(['url' => 'https://mailman.example.com', 'user' => 'user', 'password' => 'password', 'owner' => 'owner@example.com']); $typeParams = MailmanTypeRequest::new()->create(['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']); MailmanTypeRequest::new()->fails()->create(['url' => 'https://mailman.example.com', 'user' => 'newuser', 'password' => 'password', 'owner' => 'owner@example.com']);
$mailgateway = Mailgateway::factory()->type($typeParams->toData())->create(); $mailgateway = Mailgateway::factory()->type(MailmanType::class, $typeParams)->create();
Livewire::test(Form::class, ['id' => $mailgateway->id]) Livewire::test(Form::class, ['id' => $mailgateway->id])
->set('type.user', 'newuser') ->set('params.user', 'newuser')
->call('onSave') ->call('onSave')
->assertHasErrors('connection'); ->assertHasErrors('connection');
}); });

View File

@ -43,9 +43,10 @@ class SettingView extends Component
</x-slot:right> </x-slot:right>
<form id="modulesettingform" class="grow p-6 grid grid-cols-2 gap-3 items-start content-start" <form id="modulesettingform" class="grow p-6 grid grid-cols-2 gap-3 items-start content-start"
wire:submit.prevent="save"> wire:submit.prevent="save">
<x-ui::setting-intro class="col-span-full"> <div class="col-span-full text-gray-100 mb-3">
Hier kannst du Funktionen innerhalb von Adrema (Module) aktivieren oder deaktivieren und so den Funktionsumfang auf deine Bedürfnisse anpassen. <p class="text-sm">Hier kannst du Funktionen innerhalb von Adrema (Module) aktivieren oder deaktivieren
</x-ui::setting-intro> und so den Funktionsumfang auf deine Bedürfnisse anpassen.</p>
</div>
@foreach ($all as $module) @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> <x-form::lever wire:model="modules" hint="lala" :value="$module['id']" name="modules" size="sm" :label="$module['name']"></x-form::lever>
@endforeach @endforeach

View File

@ -1,69 +0,0 @@
<?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;
}
}

View File

@ -1,31 +0,0 @@
<?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');
});
}
}

View File

@ -1,90 +0,0 @@
<?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);
});

View File

@ -0,0 +1,47 @@
<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>

View File

@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<title>{{ session()->get('title') }} | {{ config('app.name') }}</title> <title>{{ $title ?? 'Page Title' }}</title>
<meta name="socketport" content="{{env('SOCKET_PORT')}}" /> <meta name="socketport" content="{{env('SOCKET_PORT')}}" />
<meta name="adrema_base_url" content="/"> <meta name="adrema_base_url" content="/">
@if(auth()->id()) @if(auth()->id())

View File

@ -61,6 +61,8 @@ use App\Maildispatcher\Actions\EditAction;
use App\Maildispatcher\Actions\IndexAction; use App\Maildispatcher\Actions\IndexAction;
use App\Maildispatcher\Actions\StoreAction as MaildispatcherStoreAction; use App\Maildispatcher\Actions\StoreAction as MaildispatcherStoreAction;
use App\Maildispatcher\Actions\UpdateAction as MaildispatcherUpdateAction; 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\ExportAction;
use App\Member\Actions\MemberDeleteAction; use App\Member\Actions\MemberDeleteAction;
use App\Member\Actions\MemberResyncAction; use App\Member\Actions\MemberResyncAction;
@ -76,6 +78,7 @@ use App\Membership\Actions\MembershipStoreAction;
use App\Membership\Actions\MembershipUpdateAction; use App\Membership\Actions\MembershipUpdateAction;
use App\Payment\SubscriptionController; use App\Payment\SubscriptionController;
Route::get('/lala', fn () => auth()->login(\App\User::first()));
Route::group(['namespace' => 'App\\Http\\Controllers'], function (): void { Route::group(['namespace' => 'App\\Http\\Controllers'], function (): void {
Auth::routes(['register' => false]); Auth::routes(['register' => false]);
}); });
@ -110,6 +113,8 @@ Route::group(['middleware' => 'auth:web'], function (): void {
Route::post('/contribution-validate', ContributionValidateAction::class)->name('contribution.validate'); Route::post('/contribution-validate', ContributionValidateAction::class)->name('contribution.validate');
// ----------------------------------- mail ------------------------------------ // ----------------------------------- 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', IndexAction::class)->name('maildispatcher.index');
Route::get('/maildispatcher/create', CreateAction::class)->name('maildispatcher.create'); Route::get('/maildispatcher/create', CreateAction::class)->name('maildispatcher.create');
Route::get('/maildispatcher/{maildispatcher}', EditAction::class)->name('maildispatcher.edit'); Route::get('/maildispatcher/{maildispatcher}', EditAction::class)->name('maildispatcher.edit');

View File

@ -2,10 +2,14 @@
arch() arch()
->expect('App') ->expect('App')
->not->toUse(['die', 'dd', 'dump']) ->not->toUse(['die', 'dd', 'dump']);
->not->toHaveFileSystemPermissions('0777');
arch() arch()
->expect('Modules') ->expect(globArch('App\*\Models'))
->not->toUse(['die', 'dd', 'dump']) ->toExtend('Illuminate\Database\Eloquent\Model')
->toBeClasses();
arch('app')
->expect('App')
->not->toHaveFileSystemPermissions('0777'); ->not->toHaveFileSystemPermissions('0777');

View File

@ -6,8 +6,8 @@ use \Mockery as M;
use App\Activity; use App\Activity;
use App\Maildispatcher\Models\Localmaildispatcher; use App\Maildispatcher\Models\Localmaildispatcher;
use App\Maildispatcher\Models\Maildispatcher; use App\Maildispatcher\Models\Maildispatcher;
use Modules\Mailgateway\Models\Mailgateway; use App\Mailgateway\Models\Mailgateway;
use Modules\Mailgateway\Types\LocalType; use App\Mailgateway\Types\LocalType;
use App\Member\Member; use App\Member\Member;
use App\Member\Membership; use App\Member\Membership;
use Tests\EndToEndTestCase; use Tests\EndToEndTestCase;

View File

@ -4,10 +4,11 @@ namespace Tests\EndToEnd\Maildispatcher;
use App\Maildispatcher\Actions\ResyncAction; use App\Maildispatcher\Actions\ResyncAction;
use App\Maildispatcher\Models\Maildispatcher; use App\Maildispatcher\Models\Maildispatcher;
use Modules\Mailgateway\Models\Mailgateway; use App\Mailgateway\Models\Mailgateway;
use Modules\Mailgateway\Types\LocalType; use App\Mailgateway\Types\LocalType;
use App\Member\FilterScope; use App\Member\FilterScope;
use App\Member\Member; use App\Member\Member;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Tests\EndToEndTestCase; use Tests\EndToEndTestCase;
class UpdateTest extends EndToEndTestCase class UpdateTest extends EndToEndTestCase

View File

@ -2,9 +2,9 @@
namespace Tests\RequestFactories; namespace Tests\RequestFactories;
use App\Mailgateway\Types\MailmanType;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Worksome\RequestFactories\RequestFactory; use Worksome\RequestFactories\RequestFactory;
use Modules\Mailgateway\Types\MailmanType;
class MailmanTypeRequest extends RequestFactory class MailmanTypeRequest extends RequestFactory
{ {

View File

@ -174,18 +174,11 @@ class TestCase extends BaseTestCase
return $this; return $this;
}); });
Testable::macro('setArray', function ($attributes, $value = null) { Testable::macro('setArray', function ($attributes) {
$self = $this; $self = $this;
if ($value === null) {
foreach ($attributes as $key => $value) { foreach ($attributes as $key => $value) {
$self = $this->set($key, $value); $self = $this->set($key, $value);
} }
return $self;
}
foreach ($value as $key => $v) {
$self = $self->set($attributes . '.' . $key, $v);
}
return $self; return $self;
}); });