Add: Store connection frontend
This commit is contained in:
parent
32e7f8c41d
commit
e9e0be83cc
|
@ -8,7 +8,7 @@ use Inertia\Inertia;
|
|||
use Inertia\Response;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class IndexAction
|
||||
class FileshareConnectionIndexAction
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
|
@ -17,7 +17,7 @@ class IndexAction
|
|||
session()->put('menu', 'setting');
|
||||
session()->put('title', 'Datei-Verbindungen');
|
||||
|
||||
return Inertia::render('fileshare/Index', [
|
||||
return Inertia::render('fileshareconnection/Index', [
|
||||
'data' => FileshareConnectionResource::collection(FileshareConnection::paginate(15)),
|
||||
]);
|
||||
}
|
|
@ -7,7 +7,7 @@ use Illuminate\Validation\ValidationException;
|
|||
use Lorisleiva\Actions\ActionRequest;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class FileshareStoreAction
|
||||
class FileshareConnectionStoreAction
|
||||
{
|
||||
use AsAction;
|
||||
|
|
@ -7,4 +7,29 @@ use Spatie\LaravelData\Data;
|
|||
abstract class ConnectionType extends Data
|
||||
{
|
||||
abstract public function check(): bool;
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
abstract public static function defaults(): array;
|
||||
|
||||
abstract public static function title(): string;
|
||||
|
||||
/**
|
||||
* @return array<int, array{label: string, key: string, type: string}>
|
||||
*/
|
||||
abstract public static function fields(): array;
|
||||
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function forSelect(): array
|
||||
{
|
||||
return collect(glob(base_path('app/Fileshare/ConnectionTypes/*')))
|
||||
->map(fn ($file) => 'App\\Fileshare\\ConnectionTypes\\' . pathinfo($file, PATHINFO_FILENAME))
|
||||
->filter(fn ($file) => $file !== static::class)
|
||||
->values()
|
||||
->map(fn ($file) => ['id' => $file, 'name' => $file::title(), 'defaults' => $file::defaults(), 'fields' => $file::fields()])
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,4 +29,33 @@ class OwncloudConnection extends ConnectionType
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static function defaults(): array
|
||||
{
|
||||
return [
|
||||
'user' => '',
|
||||
'password' => '',
|
||||
'base_url' => '',
|
||||
];
|
||||
}
|
||||
|
||||
public static function title(): string
|
||||
{
|
||||
return 'Owncloud';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static function fields(): array
|
||||
{
|
||||
return [
|
||||
['label' => 'URL', 'key' => 'base_url', 'type' => 'text'],
|
||||
['label' => 'Benutzer', 'key' => 'user', 'type' => 'text'],
|
||||
['label' => 'Passwort', 'key' => 'password', 'type' => 'password'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Fileshare;
|
||||
|
||||
use App\Fileshare\Actions\IndexAction;
|
||||
use App\Fileshare\Actions\FileshareConnectionIndexAction;
|
||||
use App\Setting\Contracts\Indexable;
|
||||
use App\Setting\LocalSettings;
|
||||
|
||||
|
@ -20,7 +20,7 @@ class FileshareSettings extends LocalSettings implements Indexable
|
|||
|
||||
public static function indexAction(): string
|
||||
{
|
||||
return IndexAction::class;
|
||||
return FileshareConnectionIndexAction::class;
|
||||
}
|
||||
|
||||
public static function title(): string
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
namespace App\Fileshare\Resources;
|
||||
|
||||
use App\Fileshare\ConnectionTypes\ConnectionType;
|
||||
use App\Fileshare\Models\FileshareConnection;
|
||||
use App\Lib\HasMeta;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/**
|
||||
|
@ -10,6 +12,9 @@ use Illuminate\Http\Resources\Json\JsonResource;
|
|||
*/
|
||||
class FileshareConnectionResource extends JsonResource
|
||||
{
|
||||
|
||||
use HasMeta;
|
||||
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
|
@ -24,6 +29,25 @@ class FileshareConnectionResource extends JsonResource
|
|||
'type' => get_class($this->type),
|
||||
'config' => $this->type->toArray(),
|
||||
'id' => $this->id,
|
||||
'type_human' => $this->type::title(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function meta(): array
|
||||
{
|
||||
return [
|
||||
'default' => [
|
||||
'name' => '',
|
||||
'type' => null,
|
||||
'config' => null,
|
||||
],
|
||||
'types' => ConnectionType::forSelect(),
|
||||
'links' => [
|
||||
'store' => route('fileshare.store'),
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
<template>
|
||||
<page-layout>
|
||||
<template #toolbar>
|
||||
<page-toolbar-button color="primary" icon="plus" @click.prevent="create">Neue Verbindung</page-toolbar-button>
|
||||
</template>
|
||||
<ui-popup v-if="single !== null" :heading="single.id ? 'Verbindung bearbeiten' : 'Neue Verbindung'" @close="cancel">
|
||||
<form @submit.prevent="submit">
|
||||
<section class="grid grid-cols-2 gap-3 mt-6">
|
||||
<f-text id="name" v-model="single.name" name="name" label="Bezeichnung" required></f-text>
|
||||
<f-select id="type" :model-value="single.type" label="Typ" name="type" :options="meta.types" required
|
||||
@update:model-value="
|
||||
single = {
|
||||
...single,
|
||||
type: $event,
|
||||
config: { ...getType($event).defaults },
|
||||
}
|
||||
"></f-select>
|
||||
<template v-for="(field, index) in getType(single.type).fields">
|
||||
<f-text v-if="field.type === 'text' || field.type === 'password' || field.type === 'email'"
|
||||
:id="field.key" :key="index" v-model="single.config[field.key]" :label="field.label"
|
||||
:type="field.type" :name="field.key" required></f-text>
|
||||
</template>
|
||||
</section>
|
||||
<section class="flex mt-4 space-x-2">
|
||||
<ui-button type="submit" class="btn-danger">Speichern</ui-button>
|
||||
<ui-button class="btn-primary" @click.prevent="single = null">Abbrechen</ui-button>
|
||||
</section>
|
||||
</form>
|
||||
</ui-popup>
|
||||
<setting-layout>
|
||||
<div class="w-full h-full pb-6">
|
||||
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm hidden md:table">
|
||||
<thead>
|
||||
<th>Bezeichnung</th>
|
||||
<th>Typ</th>
|
||||
<th>Prüfung</th>
|
||||
<th>Aktion</th>
|
||||
</thead>
|
||||
|
||||
<tr v-for="(connection, index) in data" :key="index">
|
||||
<td v-text="connection.name"></td>
|
||||
<td v-text="connection.type_human"></td>
|
||||
<td>
|
||||
<ui-boolean-display :value="connection.is_active" long-label="Verbindungsstatus"
|
||||
:label="connection.is_active ? 'Verbindung erfolgreich' : 'Verbindung fehlgeschlagen'"></ui-boolean-display>
|
||||
</td>
|
||||
<td>
|
||||
<a v-tooltip="`Bearbeiten`" href="#" class="inline-flex btn btn-warning btn-sm"
|
||||
@click.prevent="edit(connection)"><ui-sprite src="pencil"></ui-sprite></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="px-6">
|
||||
<ui-pagination class="mt-4" :value="meta" :only="['data']"></ui-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</setting-layout>
|
||||
</page-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { indexProps, useIndex } from '../../composables/useInertiaApiIndex.js';
|
||||
import SettingLayout from '../setting/Layout.vue';
|
||||
|
||||
const props = defineProps(indexProps);
|
||||
const { meta, data, create, edit, cancel, single, submit } = useIndex(props.data, 'mailgateway');
|
||||
|
||||
function getType(type) {
|
||||
if (!type) {
|
||||
return {
|
||||
fields: [],
|
||||
};
|
||||
}
|
||||
return meta.value.types.find((t) => t.id === type);
|
||||
}
|
||||
</script>
|
|
@ -19,7 +19,7 @@ use App\Invoice\Actions\InvoiceStoreAction;
|
|||
use App\Course\Actions\CourseUpdateAction;
|
||||
use App\Dashboard\Actions\IndexAction as DashboardIndexAction;
|
||||
use App\Efz\ShowEfzDocumentAction;
|
||||
use App\Fileshare\Actions\FileshareStoreAction;
|
||||
use App\Fileshare\Actions\FileshareConnectionStoreAction;
|
||||
use App\Form\Actions\ExportAction as ActionsExportAction;
|
||||
use App\Form\Actions\FormDestroyAction;
|
||||
use App\Form\Actions\FormIndexAction;
|
||||
|
@ -169,5 +169,5 @@ Route::group(['middleware' => 'auth:web'], function (): void {
|
|||
Route::delete('/participant/{participant}', ParticipantDestroyAction::class)->name('participant.destroy');
|
||||
|
||||
// ------------------------------------ fileshare -----------------------------------
|
||||
Route::post('/fileshare', FileshareStoreAction::class)->name('fileshare.store');
|
||||
Route::post('/fileshare', FileshareConnectionStoreAction::class)->name('fileshare.store');
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@ use App\Fileshare\ConnectionTypes\OwncloudConnection;
|
|||
use App\Fileshare\Models\FileshareConnection;
|
||||
use Tests\FileshareTestCase;
|
||||
|
||||
class IndexActionTest extends FileshareTestCase
|
||||
class FileshareConnectionIndexActionTest extends FileshareTestCase
|
||||
{
|
||||
public function testItListsOwncloudConnectionsThatAreActive(): void
|
||||
{
|
||||
|
@ -23,6 +23,13 @@ class IndexActionTest extends FileshareTestCase
|
|||
->assertInertiaPath('data.data.0.config.password', 'secret')
|
||||
->assertInertiaPath('data.data.0.config.base_url', env('TEST_OWNCLOUD_DOMAIN'))
|
||||
->assertInertiaPath('data.data.0.id', $connection->id)
|
||||
->assertInertiaPath('data.data.0.is_active', true);
|
||||
->assertInertiaPath('data.data.0.is_active', true)
|
||||
->assertInertiaPath('data.data.0.type_human', 'Owncloud')
|
||||
->assertInertiaPath('data.meta.default.name', '')
|
||||
->assertInertiaPath('data.meta.links.store', route('fileshare.store'))
|
||||
->assertInertiaPath('data.meta.types.0.id', OwncloudConnection::class)
|
||||
->assertInertiaPath('data.meta.types.0.name', 'Owncloud')
|
||||
->assertInertiaPath('data.meta.types.0.defaults.base_url', '')
|
||||
->assertInertiaPath('data.meta.types.0.fields.1', ['label' => 'Benutzer', 'key' => 'user', 'type' => 'text']);
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ use App\Fileshare\ConnectionTypes\OwncloudConnection;
|
|||
use App\Fileshare\Models\FileshareConnection;
|
||||
use Tests\FileshareTestCase;
|
||||
|
||||
class StoreActionTest extends FileshareTestCase
|
||||
class FileshareConnectionStoreActionTest extends FileshareTestCase
|
||||
{
|
||||
public function testItStoresAConnection(): void
|
||||
{
|
Loading…
Reference in New Issue