home-erp

git clone git://archive.git.mtrnord.blog/MTRNord/home-erp.git
Log | Files | Refs | README

commit ec41e819b61934c0f880bb46b27a10de384feca3
parent 46034f8bc8d163eac9fad1153ed06966ce7afc7a
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sat, 21 Oct 2023 19:53:54 +0200

Simplify room creation and display since nfs is only needed in compartments

Diffstat:
M.scribe/endpoints.cache/00.yaml | 2+-
M.scribe/endpoints.cache/01.yaml | 12++++++------
M.scribe/endpoints/00.yaml | 2+-
M.scribe/endpoints/01.yaml | 12++++++------
Mapp/Http/Controllers/RoomController.php | 2+-
Mdatabase/migrations/2023_10_18_142931_create_rooms_table.php | 2+-
Mresources/views/components/modal.blade.php | 102++++++++++++++++++++++++++++++++-----------------------------------------------
Mresources/views/livewire/dashboard/overview.blade.php | 96++++++++++++++++++++++++++++++++++---------------------------------------------
Mresources/views/scribe/index.blade.php | 36++++++++++++++++++------------------
9 files changed, 116 insertions(+), 150 deletions(-)

diff --git a/.scribe/endpoints.cache/00.yaml b/.scribe/endpoints.cache/00.yaml @@ -35,7 +35,7 @@ endpoints: cache-control: 'no-cache, private' content-type: application/json x-ratelimit-limit: '60' - x-ratelimit-remaining: '59' + x-ratelimit-remaining: '56' access-control-allow-origin: '*' description: null custom: [] diff --git a/.scribe/endpoints.cache/01.yaml b/.scribe/endpoints.cache/01.yaml @@ -25,12 +25,12 @@ endpoints: name: room_id description: 'The UUID of the room.' required: true - example: 9a6c7eaa-c73e-46cf-b625-a52eec78c62d + example: 9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28 type: string enumValues: [] custom: [] cleanUrlParameters: - room_id: 9a6c7eaa-c73e-46cf-b625-a52eec78c62d + room_id: 9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28 queryParameters: [] cleanQueryParameters: [] bodyParameters: [] @@ -39,12 +39,12 @@ endpoints: responses: - status: 200 - content: '{"id":"9a6c7eaa-c73e-46cf-b625-a52eec78c62d","created_at":"2023-10-21T17:02:02.000000Z","updated_at":"2023-10-21T17:02:02.000000Z","name":"Test","description":"test","cabinet_id":null}' + content: '{"id":"9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28","created_at":"2023-10-21T17:49:15.000000Z","updated_at":"2023-10-21T17:49:15.000000Z","name":"Test","description":"test","cabinet_id":null}' headers: cache-control: 'no-cache, private' content-type: application/json x-ratelimit-limit: '60' - x-ratelimit-remaining: '58' + x-ratelimit-remaining: '55' access-control-allow-origin: '*' description: null custom: [] @@ -84,12 +84,12 @@ endpoints: responses: - status: 200 - content: '[{"id":"9a6c7eaa-c73e-46cf-b625-a52eec78c62d","created_at":"2023-10-21T17:02:02.000000Z","updated_at":"2023-10-21T17:02:02.000000Z","name":"Test","description":"test","cabinet_id":null},{"id":"9a6c7f77-6a5b-4f2d-83dd-f7f10b9ce375","created_at":"2023-10-21T17:04:16.000000Z","updated_at":"2023-10-21T17:04:16.000000Z","name":"Test1","description":"Test","cabinet_id":null}]' + content: '[{"id":"9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28","created_at":"2023-10-21T17:49:15.000000Z","updated_at":"2023-10-21T17:49:15.000000Z","name":"Test","description":"test","cabinet_id":null},{"id":"9a6c90b0-b901-4b06-bc63-bc6a576eebd3","created_at":"2023-10-21T17:52:26.000000Z","updated_at":"2023-10-21T17:52:26.000000Z","name":"Test2","description":"test","cabinet_id":null}]' headers: cache-control: 'no-cache, private' content-type: application/json x-ratelimit-limit: '60' - x-ratelimit-remaining: '57' + x-ratelimit-remaining: '54' access-control-allow-origin: '*' description: null custom: [] diff --git a/.scribe/endpoints/00.yaml b/.scribe/endpoints/00.yaml @@ -33,7 +33,7 @@ endpoints: cache-control: 'no-cache, private' content-type: application/json x-ratelimit-limit: '60' - x-ratelimit-remaining: '59' + x-ratelimit-remaining: '56' access-control-allow-origin: '*' description: null custom: [] diff --git a/.scribe/endpoints/01.yaml b/.scribe/endpoints/01.yaml @@ -23,12 +23,12 @@ endpoints: name: room_id description: 'The UUID of the room.' required: true - example: 9a6c7eaa-c73e-46cf-b625-a52eec78c62d + example: 9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28 type: string enumValues: [] custom: [] cleanUrlParameters: - room_id: 9a6c7eaa-c73e-46cf-b625-a52eec78c62d + room_id: 9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28 queryParameters: [] cleanQueryParameters: [] bodyParameters: [] @@ -37,12 +37,12 @@ endpoints: responses: - status: 200 - content: '{"id":"9a6c7eaa-c73e-46cf-b625-a52eec78c62d","created_at":"2023-10-21T17:02:02.000000Z","updated_at":"2023-10-21T17:02:02.000000Z","name":"Test","description":"test","cabinet_id":null}' + content: '{"id":"9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28","created_at":"2023-10-21T17:49:15.000000Z","updated_at":"2023-10-21T17:49:15.000000Z","name":"Test","description":"test","cabinet_id":null}' headers: cache-control: 'no-cache, private' content-type: application/json x-ratelimit-limit: '60' - x-ratelimit-remaining: '58' + x-ratelimit-remaining: '55' access-control-allow-origin: '*' description: null custom: [] @@ -82,12 +82,12 @@ endpoints: responses: - status: 200 - content: '[{"id":"9a6c7eaa-c73e-46cf-b625-a52eec78c62d","created_at":"2023-10-21T17:02:02.000000Z","updated_at":"2023-10-21T17:02:02.000000Z","name":"Test","description":"test","cabinet_id":null},{"id":"9a6c7f77-6a5b-4f2d-83dd-f7f10b9ce375","created_at":"2023-10-21T17:04:16.000000Z","updated_at":"2023-10-21T17:04:16.000000Z","name":"Test1","description":"Test","cabinet_id":null}]' + content: '[{"id":"9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28","created_at":"2023-10-21T17:49:15.000000Z","updated_at":"2023-10-21T17:49:15.000000Z","name":"Test","description":"test","cabinet_id":null},{"id":"9a6c90b0-b901-4b06-bc63-bc6a576eebd3","created_at":"2023-10-21T17:52:26.000000Z","updated_at":"2023-10-21T17:52:26.000000Z","name":"Test2","description":"test","cabinet_id":null}]' headers: cache-control: 'no-cache, private' content-type: application/json x-ratelimit-limit: '60' - x-ratelimit-remaining: '57' + x-ratelimit-remaining: '54' access-control-allow-origin: '*' description: null custom: [] diff --git a/app/Http/Controllers/RoomController.php b/app/Http/Controllers/RoomController.php @@ -26,7 +26,7 @@ class RoomController extends Controller } /** - * @urlParam room_id string required The UUID of the room. Example: 9a6c7eaa-c73e-46cf-b625-a52eec78c62d + * @urlParam room_id string required The UUID of the room. Example: 9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28 * @group Rooms */ public function get_room(string $room_id): Room diff --git a/database/migrations/2023_10_18_142931_create_rooms_table.php b/database/migrations/2023_10_18_142931_create_rooms_table.php @@ -14,7 +14,7 @@ return new class extends Migration { Schema::create('rooms', function (Blueprint $table) { $table->uuid('id'); $table->timestamps(); - $table->string("name"); + $table->string("name")->unique(); $table->string("description"); $table->foreignIdFor(Cabinet::class)->nullable($value = true); }); diff --git a/resources/views/components/modal.blade.php b/resources/views/components/modal.blade.php @@ -1,77 +1,57 @@ -@props([ - 'name', - 'show' => false, - 'maxWidth' => '2xl' -]) +@props(['name', 'show' => false, 'maxWidth' => '2xl']) @php -$maxWidth = [ - 'sm' => 'sm:max-w-sm', - 'md' => 'sm:max-w-md', - 'lg' => 'sm:max-w-lg', - 'xl' => 'sm:max-w-xl', - '2xl' => 'sm:max-w-2xl', -][$maxWidth]; + $maxWidth = [ + 'sm' => 'sm:max-w-sm', + 'md' => 'sm:max-w-md', + 'lg' => 'sm:max-w-lg', + 'xl' => 'sm:max-w-xl', + '2xl' => 'sm:max-w-2xl', + ][$maxWidth]; @endphp -<div - x-data="{ - show: @js($show), - focusables() { - // All focusable element types... - let selector = 'a, button, input:not([type=\'hidden\']), textarea, select, details, [tabindex]:not([tabindex=\'-1\'])' - return [...$el.querySelectorAll(selector)] - // All non-disabled elements... - .filter(el => ! el.hasAttribute('disabled')) - }, - firstFocusable() { return this.focusables()[0] }, - lastFocusable() { return this.focusables().slice(-1)[0] }, - nextFocusable() { return this.focusables()[this.nextFocusableIndex()] || this.firstFocusable() }, - prevFocusable() { return this.focusables()[this.prevFocusableIndex()] || this.lastFocusable() }, - nextFocusableIndex() { return (this.focusables().indexOf(document.activeElement) + 1) % (this.focusables().length + 1) }, - prevFocusableIndex() { return Math.max(0, this.focusables().indexOf(document.activeElement)) -1 }, - }" - x-init="$watch('show', value => { - if (value) { - document.body.classList.add('overflow-y-hidden'); - {{ $attributes->has('focusable') ? 'setTimeout(() => firstFocusable().focus(), 100)' : '' }} - } else { - document.body.classList.remove('overflow-y-hidden'); - } - })" +<div x-data="{ + show: @js($show), + focusables() { + // All focusable element types... + let selector = 'a, button, input:not([type=\'hidden\']), textarea, select, details, [tabindex]:not([tabindex=\'-1\'])' + return [...$el.querySelectorAll(selector)] + // All non-disabled elements... + .filter(el => !el.hasAttribute('disabled')) + }, + firstFocusable() { return this.focusables()[0] }, + lastFocusable() { return this.focusables().slice(-1)[0] }, + nextFocusable() { return this.focusables()[this.nextFocusableIndex()] || this.firstFocusable() }, + prevFocusable() { return this.focusables()[this.prevFocusableIndex()] || this.lastFocusable() }, + nextFocusableIndex() { return (this.focusables().indexOf(document.activeElement) + 1) % (this.focusables().length + 1) }, + prevFocusableIndex() { return Math.max(0, this.focusables().indexOf(document.activeElement)) - 1 }, +}" x-init="$watch('show', value => { + if (value) { + document.body.classList.add('overflow-y-hidden'); + {{ $attributes->has('focusable') ? 'setTimeout(() => firstFocusable().focus(), 100)' : '' }} + } else { + document.body.classList.remove('overflow-y-hidden'); + } +})" x-on:open-modal.window="$event.detail == '{{ $name }}' ? show = true : null" - x-on:close.stop="show = false" - x-on:keydown.escape.window="show = false" + x-on:close.window.stop="show = false" x-on:keydown.escape.window="show = false" x-on:keydown.tab.prevent="$event.shiftKey || nextFocusable().focus()" - x-on:keydown.shift.tab.prevent="prevFocusable().focus()" - x-show="show" - class="fixed inset-0 overflow-y-auto px-4 py-6 sm:px-0 z-50" - style="display: {{ $show ? 'block' : 'none' }};" -> - <div - x-show="show" - class="fixed inset-0 transform transition-all" - x-on:click="show = false" - x-transition:enter="ease-out duration-300" - x-transition:enter-start="opacity-0" - x-transition:enter-end="opacity-100" - x-transition:leave="ease-in duration-200" - x-transition:leave-start="opacity-100" - x-transition:leave-end="opacity-0" - > + x-on:keydown.shift.tab.prevent="prevFocusable().focus()" x-show="show" + class="fixed inset-0 overflow-y-auto px-4 py-6 sm:px-0 z-50" style="display: {{ $show ? 'block' : 'none' }};"> + <div x-show="show" class="fixed inset-0 transform transition-all" x-on:click="show = false" + x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0" + x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200" + x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"> <div class="absolute inset-0 bg-gray-500 dark:bg-gray-900 opacity-75"></div> </div> - <div - x-show="show" + <div x-show="show" class="mb-6 bg-white dark:bg-gray-800 rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full {{ $maxWidth }} sm:mx-auto" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" - x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100" - x-transition:leave="ease-in duration-200" + x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100" x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100" - x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" - > + x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"> {{ $slot }} </div> </div> diff --git a/resources/views/livewire/dashboard/overview.blade.php b/resources/views/livewire/dashboard/overview.blade.php @@ -18,11 +18,11 @@ new class extends Component { public function createRoom(): void { $this->validate(); - $newRoom = Room::create([ + Room::create([ 'name' => $this->roomname, 'description' => $this->description, ]); - session()->flash('uuid', $newRoom->id); + $this->dispatch('close'); } public function with(): array @@ -54,57 +54,39 @@ new class extends Component { <x-modal name="create-room" :show="$errors->isNotEmpty()" focusable> <form wire:submit="createRoom" class="p-6"> - @if (session('uuid')) - <h2 class="text-lg font-medium text-gray-900 dark:text-gray-100"> - {{ __('Room successfully created') }} - </h2> - <div class="mt-6"> - <!-- TODO: Allow writing to the nfc tag directly --> - <p class="mr-3 text-sm text-gray-800 dark:text-gray-200"> - {{ __('tokens.uuid', ['uuid' => session('uuid')]) }} - </p> - </div> - <div class="mt-6 flex justify-end items-center"> - - <x-secondary-button x-on:click="$dispatch('close')"> - {{ __('Close') }} - </x-secondary-button> - </div> - @else - <h2 class="text-lg font-medium text-gray-900 dark:text-gray-100"> + <h2 class="text-lg font-medium text-gray-900 dark:text-gray-100"> + {{ __('Create Room') }} + </h2> + <div class="mt-6"> + <x-input-label for="roomname" value="{{ __('Roomname') }}" class="sr-only" /> + + <x-text-input wire:model="roomname" id="roomname" name="roomname" type="text" + class="mt-1 block w-full" placeholder="{{ __('Roomname') }}" /> + + <x-input-error :messages="$errors->get('roomname')" class="mt-2" /> + </div> + + <div class="mt-3"> + <x-input-label for="description" value="{{ __('Description') }}" class="sr-only" /> + + <x-text-input wire:model="description" id="description" name="description" type="text" + class="mt-1 block w-full" placeholder="{{ __('Description') }}" /> + + <x-input-error :messages="$errors->get('description')" class="mt-2" /> + </div> + <div class="mt-6 flex justify-end"> + <x-secondary-button x-on:click="$dispatch('close')"> + {{ __('Cancel') }} + </x-secondary-button> + + <x-primary-button class="ml-3"> {{ __('Create Room') }} - </h2> - <div class="mt-6"> - <x-input-label for="roomname" value="{{ __('Roomname') }}" class="sr-only" /> - - <x-text-input wire:model="roomname" id="roomname" name="roomname" type="text" - class="mt-1 block w-full" placeholder="{{ __('Roomname') }}" /> - - <x-input-error :messages="$errors->get('roomname')" class="mt-2" /> - </div> - - <div class="mt-3"> - <x-input-label for="description" value="{{ __('Description') }}" class="sr-only" /> - - <x-text-input wire:model="description" id="description" name="description" type="text" - class="mt-1 block w-full" placeholder="{{ __('Description') }}" /> - - <x-input-error :messages="$errors->get('description')" class="mt-2" /> - </div> - <div class="mt-6 flex justify-end"> - <x-secondary-button x-on:click="$dispatch('close')"> - {{ __('Cancel') }} - </x-secondary-button> - - <x-primary-button class="ml-3"> - {{ __('Create Room') }} - </x-primary-button> - </div> - @endif + </x-primary-button> + </div> </form> </x-modal> - @if ($rooms->items() > 0) + @if ($rooms->count() > 0) <table class="table-fixed w-full border-separate border-spacing-0 rounded-lg text-sm"> <thead class="bg-gray-700 font-medium text-slate-300 dark:text-slate-200 text-left"> <tr> @@ -114,9 +96,6 @@ new class extends Component { <th class="border-b dark:border-slate-600 p-4 pl-8 pt-3 pb-3"> {{ __('Description') }} </th> - <th class="border-b dark:border-slate-600 p-4 pl-8 pt-3 pb-3"> - {{ __('UUID') }} - </th> </tr> </thead> <tbody class="bg-white dark:bg-gray-900 text-slate-700 dark:text-slate-400"> @@ -128,9 +107,6 @@ new class extends Component { <td class="border-b border-slate-100 dark:border-slate-700 p-4 pl-8"> {{ $room->description }} </td> - <td class="border-b border-slate-100 dark:border-slate-700 p-4 pl-8"> - {{ $room->id }} - </td> </tr> @endforeach </tbody> @@ -142,3 +118,13 @@ new class extends Component { </p> @endif </section> + +<script> + document.addEventListener('livewire:initialized', () => { + Livewire.on('flash-nfc', ({ + room_id + }) => { + + }) + }) +</script> diff --git a/resources/views/scribe/index.blade.php b/resources/views/scribe/index.blade.php @@ -169,7 +169,7 @@ fetch(url, { <pre><code class="language-http">cache-control: no-cache, private content-type: application/json x-ratelimit-limit: 60 -x-ratelimit-remaining: 59 +x-ratelimit-remaining: 56 access-control-allow-origin: * </code></pre></details> <pre> @@ -283,7 +283,7 @@ You can check the Dev Tools console for debugging information.</code></pre> <div class="bash-example"> <pre><code class="language-bash">curl --request GET \ - --get "http://localhost/api/rooms/9a6c7eaa-c73e-46cf-b625-a52eec78c62d" \ + --get "http://localhost/api/rooms/9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28" \ --header "Authorization: Bearer {YOUR_AUTH_KEY}" \ --header "Content-Type: application/json" \ --header "Accept: application/json"</code></pre></div> @@ -291,7 +291,7 @@ You can check the Dev Tools console for debugging information.</code></pre> <div class="javascript-example"> <pre><code class="language-javascript">const url = new URL( - "http://localhost/api/rooms/9a6c7eaa-c73e-46cf-b625-a52eec78c62d" + "http://localhost/api/rooms/9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28" ); const headers = { @@ -318,14 +318,14 @@ fetch(url, { <pre><code class="language-http">cache-control: no-cache, private content-type: application/json x-ratelimit-limit: 60 -x-ratelimit-remaining: 58 +x-ratelimit-remaining: 55 access-control-allow-origin: * </code></pre></details> <pre> <code class="language-json" style="max-height: 300px;">{ - &quot;id&quot;: &quot;9a6c7eaa-c73e-46cf-b625-a52eec78c62d&quot;, - &quot;created_at&quot;: &quot;2023-10-21T17:02:02.000000Z&quot;, - &quot;updated_at&quot;: &quot;2023-10-21T17:02:02.000000Z&quot;, + &quot;id&quot;: &quot;9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28&quot;, + &quot;created_at&quot;: &quot;2023-10-21T17:49:15.000000Z&quot;, + &quot;updated_at&quot;: &quot;2023-10-21T17:49:15.000000Z&quot;, &quot;name&quot;: &quot;Test&quot;, &quot;description&quot;: &quot;test&quot;, &quot;cabinet_id&quot;: null @@ -419,10 +419,10 @@ You can check the Dev Tools console for debugging information.</code></pre> &nbsp; <input type="text" style="display: none" name="room_id" data-endpoint="GETapi-rooms--room_id-" - value="9a6c7eaa-c73e-46cf-b625-a52eec78c62d" + value="9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28" data-component="url"> <br> -<p>The UUID of the room. Example: <code>9a6c7eaa-c73e-46cf-b625-a52eec78c62d</code></p> +<p>The UUID of the room. Example: <code>9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28</code></p> </div> </form> @@ -475,25 +475,25 @@ fetch(url, { <pre><code class="language-http">cache-control: no-cache, private content-type: application/json x-ratelimit-limit: 60 -x-ratelimit-remaining: 57 +x-ratelimit-remaining: 54 access-control-allow-origin: * </code></pre></details> <pre> <code class="language-json" style="max-height: 300px;">[ { - &quot;id&quot;: &quot;9a6c7eaa-c73e-46cf-b625-a52eec78c62d&quot;, - &quot;created_at&quot;: &quot;2023-10-21T17:02:02.000000Z&quot;, - &quot;updated_at&quot;: &quot;2023-10-21T17:02:02.000000Z&quot;, + &quot;id&quot;: &quot;9a6c8f8c-df24-4958-86e1-2fe4bb3a7f28&quot;, + &quot;created_at&quot;: &quot;2023-10-21T17:49:15.000000Z&quot;, + &quot;updated_at&quot;: &quot;2023-10-21T17:49:15.000000Z&quot;, &quot;name&quot;: &quot;Test&quot;, &quot;description&quot;: &quot;test&quot;, &quot;cabinet_id&quot;: null }, { - &quot;id&quot;: &quot;9a6c7f77-6a5b-4f2d-83dd-f7f10b9ce375&quot;, - &quot;created_at&quot;: &quot;2023-10-21T17:04:16.000000Z&quot;, - &quot;updated_at&quot;: &quot;2023-10-21T17:04:16.000000Z&quot;, - &quot;name&quot;: &quot;Test1&quot;, - &quot;description&quot;: &quot;Test&quot;, + &quot;id&quot;: &quot;9a6c90b0-b901-4b06-bc63-bc6a576eebd3&quot;, + &quot;created_at&quot;: &quot;2023-10-21T17:52:26.000000Z&quot;, + &quot;updated_at&quot;: &quot;2023-10-21T17:52:26.000000Z&quot;, + &quot;name&quot;: &quot;Test2&quot;, + &quot;description&quot;: &quot;test&quot;, &quot;cabinet_id&quot;: null } ]</code>