diff --git a/app/Form/FormSettings.php b/app/Form/FormSettings.php index a68251ca..5a112070 100644 --- a/app/Form/FormSettings.php +++ b/app/Form/FormSettings.php @@ -30,17 +30,4 @@ class FormSettings extends LocalSettings implements Storeable 'clearCacheUrl' => 'present|string', ]; } - - /** - * @inheritdoc - */ - public function viewData(): array - { - return [ - 'data' => [ - 'registerUrl' => $this->registerUrl, - 'clearCacheUrl' => $this->clearCacheUrl, - ] - ]; - } } diff --git a/app/Http/Resources/UserResource.php b/app/Http/Resources/UserResource.php index 21ced1d7..898441d9 100644 --- a/app/Http/Resources/UserResource.php +++ b/app/Http/Resources/UserResource.php @@ -2,6 +2,7 @@ namespace App\Http\Resources; +use App\Lib\HasMeta; use App\User; use Illuminate\Http\Resources\Json\JsonResource; use Storage; @@ -11,6 +12,8 @@ use Storage; */ class UserResource extends JsonResource { + use HasMeta; + /** * Transform the resource into an array. * @@ -25,9 +28,17 @@ class UserResource extends JsonResource 'lastname' => $this->lastname, 'avatar_url' => $this->getGravatarUrl(), 'email' => $this->email, + 'id' => $this->id, 'avatar' => [ 'src' => Storage::url('avatar.png'), ], ]; } + + public static function meta(): array + { + return [ + 'links' => [] + ]; + } } diff --git a/app/Invoice/InvoiceSettings.php b/app/Invoice/InvoiceSettings.php index e1e0e4a2..ec4113b8 100644 --- a/app/Invoice/InvoiceSettings.php +++ b/app/Invoice/InvoiceSettings.php @@ -4,7 +4,6 @@ namespace App\Invoice; use App\Setting\Contracts\Storeable; use App\Setting\LocalSettings; -use Lorisleiva\Actions\ActionRequest; class InvoiceSettings extends LocalSettings implements Storeable { @@ -35,28 +34,6 @@ class InvoiceSettings extends LocalSettings implements Storeable return 'bill'; } - /** - * @inheritdoc - */ - public function viewData(): array - { - return [ - 'data' => [ - 'from_long' => $this->from_long, - 'from' => $this->from, - 'mobile' => $this->mobile, - 'email' => $this->email, - 'website' => $this->website, - 'address' => $this->address, - 'place' => $this->place, - 'zip' => $this->zip, - 'iban' => $this->iban, - 'bic' => $this->bic, - 'rememberWeeks' => $this->rememberWeeks, - ] - ]; - } - /** * @inheritdoc */ diff --git a/app/Mailgateway/MailgatewaySettings.php b/app/Mailgateway/MailgatewaySettings.php index cf202709..5e959d66 100644 --- a/app/Mailgateway/MailgatewaySettings.php +++ b/app/Mailgateway/MailgatewaySettings.php @@ -21,10 +21,16 @@ class MailgatewaySettings extends LocalSettings /** * @inheritdoc */ - public function viewData(): array + public function meta(): array { - return [ - 'data' => MailgatewayResource::collection(Mailgateway::paginate(10)), - ]; + return MailgatewayResource::meta(); + } + + /** + * @inheritdoc + */ + public function data() + { + return MailgatewayResource::collection(Mailgateway::paginate(10)); } } diff --git a/app/Module/ModuleSettings.php b/app/Module/ModuleSettings.php index 77a9db84..0ee41cc5 100644 --- a/app/Module/ModuleSettings.php +++ b/app/Module/ModuleSettings.php @@ -41,13 +41,11 @@ class ModuleSettings extends LocalSettings implements Storeable /** * @inheritdoc */ - public function viewData(): array + public function meta(): array { return [ - 'data' => [ - 'modules' => $this->modules, - ], - 'meta' => ['modules' => Module::forSelect()], + ...parent::meta(), + 'modules' => Module::forSelect() ]; } } diff --git a/app/Prevention/PreventionSettings.php b/app/Prevention/PreventionSettings.php index acefe200..649a5775 100644 --- a/app/Prevention/PreventionSettings.php +++ b/app/Prevention/PreventionSettings.php @@ -38,16 +38,4 @@ class PreventionSettings extends LocalSettings implements Storeable 'formmail' => EditorData::from($request->formmail), ]; } - - /** - * @inheritdoc - */ - public function viewData(): array - { - return [ - 'data' => [ - 'formmail' => $this->formmail, - ] - ]; - } } diff --git a/app/Setting/Actions/ViewAction.php b/app/Setting/Actions/ViewAction.php index a20e3378..a1c7a5e1 100644 --- a/app/Setting/Actions/ViewAction.php +++ b/app/Setting/Actions/ViewAction.php @@ -18,9 +18,9 @@ class ViewAction session()->put('title', $settingGroup::title()); return Inertia::render('setting/' . ucfirst($settingGroup::group()), [ - ...$settingGroup->viewData(), + 'data' => $settingGroup->data(), 'settingMenu' => app(SettingFactory::class)->getShare(), - 'storeUrl' => $settingGroup->storeUrl(), + 'meta' => $settingGroup->meta(), ]); } } diff --git a/app/Setting/LocalSettings.php b/app/Setting/LocalSettings.php index 941c4e88..3bb9e232 100644 --- a/app/Setting/LocalSettings.php +++ b/app/Setting/LocalSettings.php @@ -19,10 +19,22 @@ abstract class LocalSettings extends Settings return $this->url(); } + public function meta(): array + { + return [ + 'links' => [ + 'store' => $this->storeUrl(), + ] + ]; + } + /** - * @return array + * @return mixed */ - abstract public function viewData(): array; + public function data() + { + return $this->toArray(); + } public function beforeSave(ActionRequest $request): void { diff --git a/app/Setting/NamiSettings.php b/app/Setting/NamiSettings.php index 12dbd1d1..e64cf032 100644 --- a/app/Setting/NamiSettings.php +++ b/app/Setting/NamiSettings.php @@ -4,7 +4,6 @@ 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; @@ -64,14 +63,12 @@ class NamiSettings extends LocalSettings implements Storeable /** * @inheritdoc */ - public function viewData(): array + public function data(): array { return [ - 'data' => [ - 'mglnr' => $this->mglnr, - 'password' => '', - 'default_group_id' => $this->default_group_id, - ] + 'mglnr' => $this->mglnr, + 'password' => '', + 'default_group_id' => $this->default_group_id, ]; } } diff --git a/app/Setting/SettingServiceProvider.php b/app/Setting/SettingServiceProvider.php index bd297cb2..0999ef82 100644 --- a/app/Setting/SettingServiceProvider.php +++ b/app/Setting/SettingServiceProvider.php @@ -10,6 +10,7 @@ use App\Module\ModuleSettings; use App\Prevention\PreventionSettings; use App\Setting\Actions\StoreAction; use App\Setting\Actions\ViewAction; +use App\User\UserSettings; use Illuminate\Routing\Router; use Illuminate\Support\ServiceProvider; @@ -43,5 +44,6 @@ class SettingServiceProvider extends ServiceProvider app(SettingFactory::class)->register(FormSettings::class); app(SettingFactory::class)->register(FileshareSettings::class); app(SettingFactory::class)->register(PreventionSettings::class); + app(SettingFactory::class)->register(UserSettings::class); } } diff --git a/app/User/Actions/IndexAction.php b/app/User/Actions/IndexAction.php new file mode 100644 index 00000000..d6461057 --- /dev/null +++ b/app/User/Actions/IndexAction.php @@ -0,0 +1,18 @@ +get()); + } +} diff --git a/app/User/UserSettings.php b/app/User/UserSettings.php new file mode 100644 index 00000000..1bea49f5 --- /dev/null +++ b/app/User/UserSettings.php @@ -0,0 +1,36 @@ +get())->toArray(request()); + } +} diff --git a/bin/copydbdk b/bin/copydbdk new file mode 100755 index 00000000..8dc253dd --- /dev/null +++ b/bin/copydbdk @@ -0,0 +1,5 @@ +#!/bin/bash + +ssh dkd 'cd $ADREMA_PATH && docker compose exec db mysqldump -q -udb -p'$ADREMA_DB_PASSWORD' db --ignore-table=db.telescope_entries --ignore-table=db.failed_jobs' > db.tmp +sudo mysql scoutrobot < db.tmp + diff --git a/bin/testmigration b/bin/testmigration new file mode 100755 index 00000000..0db5877f --- /dev/null +++ b/bin/testmigration @@ -0,0 +1,7 @@ +#!/usr/bin/zsh + +php artisan migrate:fresh --env=testing +ssh dkd 'cd $ADREMA_PATH && docker compose exec db mysqldump -q -udb -p'$ADREMA_DB_PASSWORD' db --ignore-table=db.telescope_entries --ignore-table=db.failed_jobs' > dddd.sql +sudo mysql scoutrobottest < dddd.sql +php artisan migrate --env=testing + diff --git a/docker-compose.yml b/docker-compose.yml index aa27c717..50c63b6b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -92,6 +92,8 @@ services: socketi: image: quay.io/soketi/soketi:89604f268623cf799573178a7ba56b7491416bde-16-debian + ports: + - '6001:6001' environment: SOKETI_DEFAULT_APP_ID: adremaid SOKETI_DEFAULT_APP_KEY: adremakey @@ -104,6 +106,8 @@ services: meilisearch: image: getmeili/meilisearch:v1.6 + ports: + - '7700:7700' volumes: - ./data/meilisearch:/meili_data env_file: diff --git a/resources/js/composables/useInertiaApiIndex.js b/resources/js/composables/useInertiaApiIndex.js index b106ed60..1436bc6d 100644 --- a/resources/js/composables/useInertiaApiIndex.js +++ b/resources/js/composables/useInertiaApiIndex.js @@ -2,9 +2,11 @@ import {computed, ref, inject, onBeforeUnmount} from 'vue'; import {router} from '@inertiajs/vue3'; import useQueueEvents from './useQueueEvents.js'; -export function useIndex(props, siteName) { +export function useIndex(props, siteName = null) { const axios = inject('axios'); - const {startListener, stopListener} = useQueueEvents(siteName, () => reload(false)); + if (siteName !== null) { + var {startListener, stopListener} = useQueueEvents(siteName, () => reload(false)); + } const single = ref(null); const rawProps = JSON.parse(JSON.stringify(props)); const inner = { @@ -86,8 +88,10 @@ export function useIndex(props, siteName) { reload(true); } - startListener(); - onBeforeUnmount(() => stopListener()); + if (siteName !== null) { + startListener(); + onBeforeUnmount(() => stopListener()); + } return { data: inner.data, diff --git a/resources/js/views/setting/User.vue b/resources/js/views/setting/User.vue new file mode 100644 index 00000000..f7a60176 --- /dev/null +++ b/resources/js/views/setting/User.vue @@ -0,0 +1,61 @@ + + + diff --git a/resources/js/views/setting/useSettings.js b/resources/js/views/setting/useSettings.js index 8ab758d3..ebdd5d70 100644 --- a/resources/js/views/setting/useSettings.js +++ b/resources/js/views/setting/useSettings.js @@ -1,11 +1,11 @@ -import {useIndex} from '../../composables/useIndex.js'; +import {useIndex} from '../../composables/useInertiaApiIndex.js'; import SettingLayout from './Layout.vue'; export function useSettings(props) { const {data, meta, router} = useIndex(props); function submit() { - router.post(props.storeUrl, {...data.value}); + router.post(meta.value.links.store, {...data.value}); } return { @@ -22,10 +22,6 @@ const props = { type: Object, required: true, }, - storeUrl: { - type: String, - required: true, - }, settingMenu: { type: Object, required: true, diff --git a/tests/Feature/Permission/UserIndexTest.php b/tests/Feature/Permission/UserIndexTest.php new file mode 100644 index 00000000..0ceb1364 --- /dev/null +++ b/tests/Feature/Permission/UserIndexTest.php @@ -0,0 +1,35 @@ +login()->loginNami(); + $this->get(route('setting.view', ['settingGroup' => 'user'])) + ->assertOk() + ->assertComponent('setting/User'); + } + + public function testItListsUsers(): void + { + $this->login()->loginNami(); + auth()->user()->update(['firstname' => 'Jane', 'lastname' => 'Doe']); + User::factory()->create(['firstname' => 'John', 'lastname' => 'Doe']); + $anna = User::factory()->create(['firstname' => 'Anna', 'lastname' => 'Doe']); + $this->get(route('api.user.index')) + ->assertJsonPath('data.0.firstname', 'Anna') + ->assertJsonPath('data.0.lastname', 'Doe') + ->assertJsonPath('data.0.id', $anna->id) + ->assertJsonPath('data.1.firstname', 'Jane') + ->assertJsonPath('data.2.firstname', 'John'); + } +}