parent
50dc714f18
commit
f1c55bedce
|
@ -11,7 +11,7 @@ class RedirectIfNotInitializedMiddleware
|
||||||
/**
|
/**
|
||||||
* @var array<int, string>
|
* @var array<int, string>
|
||||||
*/
|
*/
|
||||||
public array $dontRedirect = ['initialize.form', 'initialize.store', 'nami.login-check', 'nami.search'];
|
public array $dontRedirect = ['initialize.form', 'initialize.store', 'nami.login-check', 'nami.search', 'nami.get-search-layer'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Initialize\Actions;
|
||||||
|
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Lorisleiva\Actions\ActionRequest;
|
||||||
|
use Lorisleiva\Actions\Concerns\AsAction;
|
||||||
|
use Zoomyboy\LaravelNami\Data\SearchLayerOption;
|
||||||
|
use Zoomyboy\LaravelNami\Enum\SearchLayer;
|
||||||
|
use Zoomyboy\LaravelNami\Nami;
|
||||||
|
|
||||||
|
class NamiGetSearchLayerAction
|
||||||
|
{
|
||||||
|
use AsAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $input
|
||||||
|
*
|
||||||
|
* @return Collection<int, SearchLayerOption>
|
||||||
|
*/
|
||||||
|
public function handle(array $input): Collection
|
||||||
|
{
|
||||||
|
return Nami::login((int) $input['mglnr'], $input['password'])->searchLayerOptions(
|
||||||
|
SearchLayer::from($input['layer'] ?: 0),
|
||||||
|
$input['parent'] ?: null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'mglnr' => 'required|numeric|min:0',
|
||||||
|
'password' => 'required|string',
|
||||||
|
'parent' => 'present',
|
||||||
|
'layer' => 'required|numeric',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function asController(ActionRequest $request): JsonResponse
|
||||||
|
{
|
||||||
|
$response = $this->handle($request->validated());
|
||||||
|
|
||||||
|
return response()->json($response);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
Subproject commit 33875d36fa5bd6fab4147e95f4aa705092f42d93
|
Subproject commit c5ea29af1bb1591238bb037da93739f5bd874334
|
|
@ -42,6 +42,14 @@ Vue.component('toolbar-button', ToolbarButton);
|
||||||
Vue.component('page-layout', PageLayout);
|
Vue.component('page-layout', PageLayout);
|
||||||
Vue.component('save-button', () => import(/* webpackChunkName: "form" */ './components/SaveButton'));
|
Vue.component('save-button', () => import(/* webpackChunkName: "form" */ './components/SaveButton'));
|
||||||
|
|
||||||
|
// ------------------------------ Full components ------------------------------
|
||||||
|
Vue.component('full-page-heading', () => import(/* webpackChunkName: "full" */ './components/Full/PageHeading.vue'));
|
||||||
|
|
||||||
|
// ------------------------------- UI Components -------------------------------
|
||||||
|
Vue.component('ui-button', () => import(/* webpackChunkName: "ui" */ './components/Ui/Button.vue'));
|
||||||
|
Vue.component('ui-spinner', () => import(/* webpackChunkName: "ui" */ './components/Ui/Spinner.vue'));
|
||||||
|
|
||||||
|
// ----------------------------------- init ------------------------------------
|
||||||
const el = document.getElementById('app');
|
const el = document.getElementById('app');
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<h1 class="text-xl border-b-2 pb-1 mb-4 text-primary-100 text-center border-primary-800"><slot></slot></h1>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {};
|
||||||
|
</script>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<template>
|
||||||
|
<button class="btn btn-primary relative group">
|
||||||
|
<div :class="{hidden: !isLoading, flex: isLoading}" class="absolute items-center top-0 h-full left-0 ml-2">
|
||||||
|
<ui-spinner class="border-primary-400 w-6 h-6 group-hover:border-primary-200"></ui-spinner>
|
||||||
|
</div>
|
||||||
|
Weiter
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {menuStore} from '../../stores/menuStore.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data: function () {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isLoading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,57 @@
|
||||||
|
<template>
|
||||||
|
<div :class="`spin-${type}`">
|
||||||
|
<div v-if="type === 'ring'"></div>
|
||||||
|
<div v-if="type === 'ring'"></div>
|
||||||
|
<div v-if="type === 'ring'"></div>
|
||||||
|
<div v-if="type === 'ring'"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: () => 'ring',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.spin-ring {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.spin-ring div {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 3px solid #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||||
|
border-top-color: inherit;
|
||||||
|
border-right-color: transparent;
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
border-left-color: transparent;
|
||||||
|
}
|
||||||
|
.spin-ring div:nth-child(1) {
|
||||||
|
animation-delay: -0.45s;
|
||||||
|
}
|
||||||
|
.spin-ring div:nth-child(2) {
|
||||||
|
animation-delay: -0.3s;
|
||||||
|
}
|
||||||
|
.spin-ring div:nth-child(3) {
|
||||||
|
animation-delay: -0.15s;
|
||||||
|
}
|
||||||
|
@keyframes ring {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="app" class="bg-gray-900 font-sans flex flex-col grow items-center justify-center">
|
<div id="app" class="bg-gray-900 font-sans flex flex-col grow items-center justify-center p-6">
|
||||||
<v-notification class="fixed z-40 right-0 bottom-0 mb-3 mr-3"></v-notification>
|
<v-notification class="fixed z-40 right-0 bottom-0 mb-3 mr-3"></v-notification>
|
||||||
<div class="bg-gray-800 rounded-xl overflow-hidden shadow-lg p-6">
|
<div class="bg-gray-800 rounded-xl overflow-hidden shadow-lg p-6">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
|
|
@ -1,63 +1,57 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="step === 0">
|
<div v-if="step === 0">
|
||||||
|
<full-page-heading>Willkommen im Adrema-Setup.<br /></full-page-heading>
|
||||||
<div class="prose prose-invert">
|
<div class="prose prose-invert">
|
||||||
<p>Willkommen im Adrema-Setup.<br /></p>
|
<p>Bitte gib deine NaMi-Zugangsdaten ein,<br />um eine erste Synchronisation durchzuführen.</p>
|
||||||
<p>
|
|
||||||
Bitte gib deine NaMi-Zugangsdaten ein,<br />
|
|
||||||
um eine erste Synchronisation durchzuführen.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<form @submit.prevent="check" class="grid gap-3 mt-5">
|
<form @submit.prevent="check" class="grid gap-3 mt-5">
|
||||||
<f-text v-model="values.mglnr" label="Mitgliedsnummer" name="mglnr" id="mglnr" type="tel" required></f-text>
|
<f-text v-model="values.mglnr" label="Mitgliedsnummer" name="mglnr" id="mglnr" type="tel" required></f-text>
|
||||||
<f-text v-model="values.password" type="password" label="Passwort" name="password" id="password" required></f-text>
|
<f-text v-model="values.password" type="password" label="Passwort" name="password" id="password" required></f-text>
|
||||||
<button type="submit" class="btn w-full btn-primary mt-6 inline-block">Weiter</button>
|
<ui-button class="mt-6" :is-loading="loading" type="submit">Weiter</ui-button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="step === 1" class="flex flex-col" style="width: 90vw; height: 90vh">
|
<div v-if="step === 1" class="grid grid-cols-5 w-full gap-3">
|
||||||
<form @submit.prevent="storeSearch" class="border-2 border-primary-700 border-solid p-3 rounded-lg grid grid-cols-3 gap-3 flex-none">
|
<full-page-heading class="col-span-full !mb-0">Suchkriterien festlegen</full-page-heading>
|
||||||
|
<form @submit.prevent="storeSearch" class="border-2 border-primary-800 border-solid p-3 rounded-lg grid gap-3 col-span-2">
|
||||||
<div class="prose prose-invert max-w-none col-span-full">
|
<div class="prose prose-invert max-w-none col-span-full">
|
||||||
<p>
|
<p>
|
||||||
Lege hier die Suchkriterien für den Abruf der Mitglieder-Daten fest. Mit diesen Suchkriterien wird im Anschluss eine Mitgliedersuche in NaMi durchgeführt. Alle Mitglieder, die
|
Lege hier die Suchkriterien für den Abruf der Mitglieder-Daten fest. Mit diesen Suchkriterien wird im Anschluss eine Mitgliedersuche in NaMi durchgeführt. Alle Mitglieder, die
|
||||||
dann dort auftauchen werden in die Adrema übernommen. Dir wird hier eine Vorschau eingeblendet, damit du sicherstellen kannst, dass die Suchkriterien die richtigen sind.
|
dann dort auftauchen werden in die Adrema übernommen. Dir wird hier eine Vorschau eingeblendet, damit du sicherstellen kannst, dass die Suchkriterien die richtigen sind.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
|
||||||
Außerdem werden diese Suchkriterien bei jedem neuen Abgleich (der automatisch täglich erfolgt) angewendet. Du kannst die Suchkriterien in den globalen Einstellungen jederzeit
|
|
||||||
ändern.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<f-text
|
<f-select
|
||||||
v-model="values.params.gruppierung1Id"
|
v-model="values.params.gruppierung1Id"
|
||||||
label="Diözesan-Gruppierung"
|
label="Diözesan-Gruppierung"
|
||||||
name="gruppierung1Id"
|
name="gruppierung1Id"
|
||||||
id="gruppierung1Id"
|
id="gruppierung1Id"
|
||||||
type="tel"
|
|
||||||
size="sm"
|
size="sm"
|
||||||
@input="search"
|
:options="searchLayerOptions[0]"
|
||||||
|
@input="loadSearchLayer(1, $event, search)"
|
||||||
hint="Gruppierungs-Nummer einer Diözese, auf die die Mitglieder passen sollen. I.d.R. ist das die Gruppierungsnummer deiner Diözese. Entspricht dem Feld '1. Ebene' in der NaMi Suche."
|
hint="Gruppierungs-Nummer einer Diözese, auf die die Mitglieder passen sollen. I.d.R. ist das die Gruppierungsnummer deiner Diözese. Entspricht dem Feld '1. Ebene' in der NaMi Suche."
|
||||||
></f-text>
|
></f-select>
|
||||||
<f-text
|
<f-select
|
||||||
v-model="values.params.gruppierung2Id"
|
v-model="values.params.gruppierung2Id"
|
||||||
label="Bezirks-Gruppierung"
|
label="Bezirks-Gruppierung"
|
||||||
name="gruppierung2Id"
|
name="gruppierung2Id"
|
||||||
id="gruppierung2Id"
|
id="gruppierung2Id"
|
||||||
type="tel"
|
|
||||||
hint="Gruppierungs-Nummer eines Bezirks, auf die die Mitglieder passen sollen. I.d.R. ist das die Gruppierungsnummer deines Bezirks. Entspricht dem Feld '2. Ebene' in der NaMi Suche. Fülle dieses Feld aus, um Mitglieder auf einen bestimmten Bezirk zu begrenzen."
|
hint="Gruppierungs-Nummer eines Bezirks, auf die die Mitglieder passen sollen. I.d.R. ist das die Gruppierungsnummer deines Bezirks. Entspricht dem Feld '2. Ebene' in der NaMi Suche. Fülle dieses Feld aus, um Mitglieder auf einen bestimmten Bezirk zu begrenzen."
|
||||||
:disabled="!values.params.gruppierung1Id"
|
:disabled="!values.params.gruppierung1Id"
|
||||||
@input="search"
|
@input="loadSearchLayer(2, $event, search)"
|
||||||
size="sm"
|
size="sm"
|
||||||
></f-text>
|
:options="searchLayerOptions[1]"
|
||||||
<f-text
|
></f-select>
|
||||||
|
<f-select
|
||||||
v-model="values.params.gruppierung3Id"
|
v-model="values.params.gruppierung3Id"
|
||||||
label="Stammes-Gruppierung"
|
label="Stammes-Gruppierung"
|
||||||
name="gruppierung3Id"
|
name="gruppierung3Id"
|
||||||
id="gruppierung3Id"
|
id="gruppierung3Id"
|
||||||
type="tel"
|
|
||||||
size="sm"
|
size="sm"
|
||||||
@input="search"
|
@input="search"
|
||||||
hint="Gruppierungs-Nummer deines Stammes, auf die die Mitglieder passen sollen. I.d.R. ist das die Gruppierungsnummer deines Stammes. Entspricht dem Feld '3. Ebene' in der NaMi Suche. Fülle dieses Feld aus, um Mitglieder auf einen bestimmten Stamm zu beschränken."
|
hint="Gruppierungs-Nummer deines Stammes, auf die die Mitglieder passen sollen. I.d.R. ist das die Gruppierungsnummer deines Stammes. Entspricht dem Feld '3. Ebene' in der NaMi Suche. Fülle dieses Feld aus, um Mitglieder auf einen bestimmten Stamm zu beschränken."
|
||||||
:disabled="!values.params.gruppierung1Id || !values.params.gruppierung2Id"
|
:disabled="!values.params.gruppierung1Id || !values.params.gruppierung2Id"
|
||||||
></f-text>
|
:options="searchLayerOptions[2]"
|
||||||
|
></f-select>
|
||||||
<f-select
|
<f-select
|
||||||
v-model="values.params.mglStatusId"
|
v-model="values.params.mglStatusId"
|
||||||
label="Mitglieds-Status"
|
label="Mitglieds-Status"
|
||||||
|
@ -86,12 +80,12 @@
|
||||||
hint="Mitglieder finden, die direktes Mitglied in einer Untergruppe der kleinsten befüllten Gruppierung sind."
|
hint="Mitglieder finden, die direktes Mitglied in einer Untergruppe der kleinsten befüllten Gruppierung sind."
|
||||||
size="sm"
|
size="sm"
|
||||||
></f-switch>
|
></f-switch>
|
||||||
<div class="col-span-full">
|
<div class="col-span-full flex justify-center">
|
||||||
<button type="submit" class="btn btn-primary btn-sm">Weiter</button>
|
<ui-button :is-loading="loading" class="px-10" type="submit">Weiter</ui-button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<section class="grow border-2 border-primary-700 border-solid p-3 rounded-lg mt-4" v-if="preview !== null && preview.data.length">
|
<section class="col-span-3 text-sm col-span-3" v-if="preview !== null && preview.data.length">
|
||||||
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm hidden md:table">
|
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm hidden md:table">
|
||||||
<thead>
|
<thead>
|
||||||
<th>GruppierungsNr</th>
|
<th>GruppierungsNr</th>
|
||||||
|
@ -114,9 +108,10 @@
|
||||||
<v-pages class="mt-4" :value="preview" @reload="reloadPage"></v-pages>
|
<v-pages class="mt-4" :value="preview" @reload="reloadPage"></v-pages>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="grow items-center justify-center flex text-xl text-gray-200 border-2 border-primary-700 border-solid p-3 rounded-lg mt-4" v-else>Keine Mitglieder gefunden</section>
|
<section class="col-span-3 items-center justify-center flex text-xl text-gray-200 border-2 border-primary-800 border-solid p-3 rounded-lg mt-4" v-else>Keine Mitglieder gefunden</section>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="step === 2">
|
<div v-if="step === 2">
|
||||||
|
<full-page-heading>Standard-Gruppierung</full-page-heading>
|
||||||
<div class="prose prose-invert">
|
<div class="prose prose-invert">
|
||||||
<p>Bitte gib hier deine Standard-Gruppierungsnummer ein.</p>
|
<p>Bitte gib hier deine Standard-Gruppierungsnummer ein.</p>
|
||||||
<p>Dieser Gruppierung werden Mitglieder automatisch zugeordnet,<br />falls nichts anderes angegeben wurde.</p>
|
<p>Dieser Gruppierung werden Mitglieder automatisch zugeordnet,<br />falls nichts anderes angegeben wurde.</p>
|
||||||
|
@ -128,6 +123,7 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="step === 3">
|
<div v-if="step === 3">
|
||||||
|
<full-page-heading>Einrichtung abgeschlossen</full-page-heading>
|
||||||
<div class="prose prose-invert">
|
<div class="prose prose-invert">
|
||||||
<p>Wir werden nun die Mitgliederdaten anhand deiner festgelegten Kriterien abrufen.</p>
|
<p>Wir werden nun die Mitgliederdaten anhand deiner festgelegten Kriterien abrufen.</p>
|
||||||
<p>Per Klick auf "Abschließen" gelangst du zum Dashboard</p>
|
<p>Per Klick auf "Abschließen" gelangst du zum Dashboard</p>
|
||||||
|
@ -150,6 +146,8 @@ export default {
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
|
searchLayerOptions: [[], [], []],
|
||||||
|
loading: false,
|
||||||
preview: null,
|
preview: null,
|
||||||
states: [
|
states: [
|
||||||
{id: 'INAKTIV', name: 'Inaktiv'},
|
{id: 'INAKTIV', name: 'Inaktiv'},
|
||||||
|
@ -188,23 +186,57 @@ export default {
|
||||||
await this.loadSearchResult(page);
|
await this.loadSearchResult(page);
|
||||||
},
|
},
|
||||||
async check() {
|
async check() {
|
||||||
|
this.loading = true;
|
||||||
try {
|
try {
|
||||||
await this.axios.post('/nami/login-check', this.values);
|
await this.axios.post('/nami/login-check', this.values);
|
||||||
this.step = 1;
|
|
||||||
await this.loadSearchResult(1);
|
await this.loadSearchResult(1);
|
||||||
|
await this.loadSearchLayer(0, null, () => '');
|
||||||
|
this.step = 1;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.errorsFromException(e);
|
this.errorsFromException(e);
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
search: debounce(async function () {
|
search: debounce(async function () {
|
||||||
await this.loadSearchResult(1);
|
await this.loadSearchResult(1);
|
||||||
}, 500),
|
}, 500),
|
||||||
|
async loadSearchLayer(parentLayer, parent, after) {
|
||||||
|
this.loading = true;
|
||||||
|
try {
|
||||||
|
var result = await this.axios.post('/nami/get-search-layer', {...this.values, layer: parentLayer, parent});
|
||||||
|
|
||||||
|
this.searchLayerOptions = this.searchLayerOptions.map((layers, index) => {
|
||||||
|
if (index < parentLayer) {
|
||||||
|
return layers;
|
||||||
|
}
|
||||||
|
|
||||||
|
var groupIndex = index + 1;
|
||||||
|
this.values.params[`gruppierung${groupIndex}Id`] = null;
|
||||||
|
|
||||||
|
if (index === parentLayer) {
|
||||||
|
return result.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
|
after();
|
||||||
|
} catch (e) {
|
||||||
|
this.errorsFromException(e);
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
async loadSearchResult(page) {
|
async loadSearchResult(page) {
|
||||||
|
this.loading = true;
|
||||||
try {
|
try {
|
||||||
var result = await this.axios.post('/nami/search', {...this.values, page: page});
|
var result = await this.axios.post('/nami/search', {...this.values, page: page});
|
||||||
this.preview = result.data;
|
this.preview = result.data;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.errorsFromException(e);
|
this.errorsFromException(e);
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,6 +17,7 @@ use App\Dashboard\Actions\IndexAction as DashboardIndexAction;
|
||||||
use App\Efz\ShowEfzDocumentAction;
|
use App\Efz\ShowEfzDocumentAction;
|
||||||
use App\Initialize\Actions\InitializeAction;
|
use App\Initialize\Actions\InitializeAction;
|
||||||
use App\Initialize\Actions\InitializeFormAction;
|
use App\Initialize\Actions\InitializeFormAction;
|
||||||
|
use App\Initialize\Actions\NamiGetSearchLayerAction;
|
||||||
use App\Initialize\Actions\NamiLoginCheckAction;
|
use App\Initialize\Actions\NamiLoginCheckAction;
|
||||||
use App\Initialize\Actions\NamiSearchAction;
|
use App\Initialize\Actions\NamiSearchAction;
|
||||||
use App\Member\Actions\ExportAction;
|
use App\Member\Actions\ExportAction;
|
||||||
|
@ -41,6 +42,7 @@ Route::group(['namespace' => 'App\\Http\\Controllers'], function (): void {
|
||||||
Route::group(['middleware' => 'auth:web'], function (): void {
|
Route::group(['middleware' => 'auth:web'], function (): void {
|
||||||
Route::get('/', DashboardIndexAction::class)->name('home');
|
Route::get('/', DashboardIndexAction::class)->name('home');
|
||||||
Route::post('/nami/login-check', NamiLoginCheckAction::class)->name('nami.login-check');
|
Route::post('/nami/login-check', NamiLoginCheckAction::class)->name('nami.login-check');
|
||||||
|
Route::post('/nami/get-search-layer', NamiGetSearchLayerAction::class)->name('nami.get-search-layer');
|
||||||
Route::post('/nami/search', NamiSearchAction::class)->name('nami.search');
|
Route::post('/nami/search', NamiSearchAction::class)->name('nami.search');
|
||||||
Route::post('/api/member/search', SearchAction::class)->name('member.search');
|
Route::post('/api/member/search', SearchAction::class)->name('member.search');
|
||||||
Route::get('/initialize', InitializeFormAction::class)->name('initialize.form');
|
Route::get('/initialize', InitializeFormAction::class)->name('initialize.form');
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Initializer;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
|
use Tests\TestCase;
|
||||||
|
use Zoomyboy\LaravelNami\Authentication\Auth;
|
||||||
|
use Zoomyboy\LaravelNami\Fakes\SearchLayerFake;
|
||||||
|
|
||||||
|
class GetSearchLayerActionTest extends TestCase
|
||||||
|
{
|
||||||
|
use DatabaseTransactions;
|
||||||
|
|
||||||
|
public function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->login();
|
||||||
|
Auth::success(333, 'secret');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItFindsRoots(): void
|
||||||
|
{
|
||||||
|
$this->withoutExceptionHandling();
|
||||||
|
app(SearchLayerFake::class)->fetches('1', [
|
||||||
|
['descriptor' => 'aa', 'id' => 5],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->postJson('/nami/get-search-layer', [
|
||||||
|
'layer' => 0,
|
||||||
|
'parent' => null,
|
||||||
|
'mglnr' => 333,
|
||||||
|
'password' => 'secret',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertJsonPath('0.name', 'aa');
|
||||||
|
$response->assertJsonPath('0.id', 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItFindsFirstLayer(): void
|
||||||
|
{
|
||||||
|
$this->withoutExceptionHandling();
|
||||||
|
app(SearchLayerFake::class)->fetches('2/gruppierung1/20', [
|
||||||
|
['descriptor' => 'aa', 'id' => 5],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->postJson('/nami/get-search-layer', [
|
||||||
|
'layer' => 1,
|
||||||
|
'parent' => 20,
|
||||||
|
'mglnr' => 333,
|
||||||
|
'password' => 'secret',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertJsonPath('0.name', 'aa');
|
||||||
|
$response->assertJsonPath('0.id', 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItFindsSecondLayer(): void
|
||||||
|
{
|
||||||
|
$this->withoutExceptionHandling();
|
||||||
|
app(SearchLayerFake::class)->fetches('3/gruppierung2/30', [
|
||||||
|
['descriptor' => 'aa', 'id' => 5],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->postJson('/nami/get-search-layer', [
|
||||||
|
'layer' => 2,
|
||||||
|
'parent' => 30,
|
||||||
|
'mglnr' => 333,
|
||||||
|
'password' => 'secret',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertJsonPath('0.name', 'aa');
|
||||||
|
$response->assertJsonPath('0.id', 5);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue