Преглед изворни кода

Merge pull request #315 from IceToast/servercreation_resouce_card

servers/create - updated UI
Dennis пре 3 година
родитељ
комит
1858cf0db2
3 измењених фајлова са 160 додато и 192 уклоњено
  1. 17 1
      public/css/app.css
  2. 0 1
      public/js/app.js
  3. 143 190
      resources/views/servers/create.blade.php

Разлика између датотеке није приказан због своје велике величине
+ 17 - 1
public/css/app.css


Разлика између датотеке није приказан због своје велике величине
+ 0 - 1
public/js/app.js


+ 143 - 190
resources/views/servers/create.blade.php

@@ -24,41 +24,41 @@
 
     <!-- MAIN CONTENT -->
     <section x-data="serverApp()" class="content">
-        <div class="container">
-
+        <div class="container-xxl">
             <!-- FORM -->
-            <form action="{{route('servers.store')}}" method="post" class="row">
+            <form action="{{ route('servers.store') }}" method="post" class="row justify-content-center">
                 @csrf
-                <div class="col-md-8">
+                <div class="col-xl-6 col-lg-8 col-md-8 col-sm-10">
                     <div class="card">
                         <div class="card-header">
-                            <div class="card-title"><i class="fas fa-cogs mr-2"></i>{{__('Server configuration')}}</div>
+                            <div class="card-title"><i class="fas fa-cogs mr-2"></i>{{ __('Server configuration') }}
+                            </div>
                         </div>
 
-                        @if($productCount === 0 || $nodeCount === 0 || count($nests) === 0 || count($eggs) === 0 )
+                        @if ($productCount === 0 || $nodeCount === 0 || count($nests) === 0 || count($eggs) === 0)
                             <div class="alert alert-danger p-2 m-2">
-                                <h5><i class="icon fas fa-exclamation-circle"></i>{{__('Error!')}}</h5>
+                                <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Error!') }}</h5>
                                 <p class="pl-4">
-                                    @if(Auth::user()->role == 'admin')
-                                        {{__('Make sure to link your products to nodes and eggs.')}} <br>
-                                        {{__('There has to be at least 1 valid product for server creation')}}
+                                    @if (Auth::user()->role == 'admin')
+                                        {{ __('Make sure to link your products to nodes and eggs.') }} <br>
+                                        {{ __('There has to be at least 1 valid product for server creation') }}
                                     @endif
                                 </p>
                                 <ul>
-                                    @if($productCount === 0 )
-                                        <li> {{__('No products available!')}}</li>
+                                    @if ($productCount === 0)
+                                        <li> {{ __('No products available!') }}</li>
                                     @endif
 
-                                    @if($nodeCount === 0 )
-                                        <li>{{__('No nodes have been linked!')}}</li>
+                                    @if ($nodeCount === 0)
+                                        <li>{{ __('No nodes have been linked!') }}</li>
                                     @endif
 
-                                    @if(count($nests) === 0 )
-                                        <li>{{__('No nests available!')}}</li>
+                                    @if (count($nests) === 0)
+                                        <li>{{ __('No nests available!') }}</li>
                                     @endif
 
-                                    @if(count($eggs) === 0 )
-                                        <li>{{__('No eggs have been linked!')}}</li>
+                                    @if (count($eggs) === 0)
+                                        <li>{{ __('No eggs have been linked!') }}</li>
                                     @endif
                                 </ul>
                             </div>
@@ -68,8 +68,8 @@
                         <div x-show="loading" class="overlay dark">
                             <i class="fas fa-2x fa-sync-alt"></i>
                         </div>
-                        <div class="card-body">
 
+                        <div class="card-body">
                             @if ($errors->any())
                                 <div class="alert alert-danger">
                                     <ul class="list-group pl-3">
@@ -81,29 +81,25 @@
                             @endif
 
                             <div class="form-group">
-                                <label for="name">{{__('Name')}}</label>
+                                <label for="name">{{ __('Name') }}</label>
                                 <input x-model="name" id="name" name="name" type="text" required="required"
-                                       class="form-control @error('name') is-invalid @enderror">
-
+                                    class="form-control @error('name') is-invalid @enderror">
                                 @error('name')
-                                <div class="invalid-feedback">
-                                    {{ $message }}
-                                </div>
+                                    <div class="invalid-feedback">
+                                        {{ $message }}
+                                    </div>
                                 @enderror
                             </div>
 
                             <div class="row">
                                 <div class="col-md-6">
                                     <div class="form-group">
-                                        <label for="nest">{{__('Software / Games')}}</label>
-                                        <select class="custom-select"
-                                                required
-                                                name="nest"
-                                                id="nest"
-                                                x-model="selectedNest"
-                                                @change="setEggs();">
-                                            <option selected disabled hidden
-                                                    value="null">{{count($nests) > 0 ? __('Please select software ...') : __('---')}}</option>
+                                        <label for="nest">{{ __('Software / Games') }}</label>
+                                        <select class="custom-select" required name="nest" id="nest" x-model="selectedNest"
+                                            @change="setEggs();">
+                                            <option selected disabled hidden value="null">
+                                                {{ count($nests) > 0 ? __('Please select software ...') : __('---') }}
+                                            </option>
                                             @foreach ($nests as $nest)
                                                 <option value="{{ $nest->id }}">{{ $nest->name }}</option>
                                             @endforeach
@@ -111,21 +107,15 @@
 
                                     </div>
                                 </div>
-
                                 <div class="col-md-6">
                                     <div class="form-group">
-                                        <label for="egg">{{__('Specification')}}</label>
+                                        <label for="egg">{{ __('Specification ') }}</label>
                                         <div>
-                                            <select id="egg"
-                                                    required
-                                                    name="egg"
-                                                    :disabled="eggs.length == 0"
-                                                    x-model="selectedEgg"
-                                                    @change="fetchLocations();"
-                                                    required="required"
-                                                    class="custom-select">
-                                                <option x-text="getEggInputText()"
-                                                        selected disabled hidden value="null"></option>
+                                            <select id="egg" required name="egg" :disabled="eggs.length == 0"
+                                                x-model="selectedEgg" @change="fetchLocations();" required="required"
+                                                class="custom-select">
+                                                <option x-text="getEggInputText()" selected disabled hidden value="null">
+                                                </option>
                                                 <template x-for="egg in eggs" :key="egg.id">
                                                     <option x-text="egg.name" :value="egg.id"></option>
                                                 </template>
@@ -136,25 +126,17 @@
                             </div>
 
                             <div class="form-group">
-                                <label for="node">{{__('Node')}}</label>
-                                <select name="node"
-                                        required
-                                        id="node"
-                                        x-model="selectedNode"
-                                        :disabled="!fetchedLocations"
-                                        @change="fetchProducts();"
-                                        class="custom-select">
-                                    <option
-                                        x-text="getNodeInputText()"
-                                        disabled selected hidden value="null">
+                                <label for="node">{{ __('Node') }}</label>
+                                <select name="node" required id="node" x-model="selectedNode" :disabled="!fetchedLocations"
+                                    @change="fetchProducts();" class="custom-select">
+                                    <option x-text="getNodeInputText()" disabled selected hidden value="null">
                                     </option>
 
                                     <template x-for="location in locations" :key="location.id">
                                         <optgroup :label="location.name">
 
                                             <template x-for="node in location.nodes" :key="node.id">
-                                                <option x-text="node.name"
-                                                        :value="node.id">
+                                                <option x-text="node.name" :value="node.id">
 
                                                 </option>
                                             </template>
@@ -163,127 +145,90 @@
 
                                 </select>
                             </div>
-
-
-                            <div class="form-group">
-                                <label for="product">{{__('Resources')}}</label>
-                                <select name="product"
-                                        required
-                                        id="product"
-                                        :disabled="!fetchedProducts"
-                                        x-model="selectedProduct"
-                                        @change="updateSelectedObjects()"
-                                        class="custom-select">
-                                    <option
-                                        x-text="getProductInputText()"
-                                        disabled selected hidden value="null"></option>
-                                    <template x-for="product in products" :key="product.id">
-                                        <option :disabled="product.minimum_credits > user.credits"
-                                                x-text="getProductOptionText(product)"
-                                                :value="product.id">
-                                        </option>
-                                    </template>
-                                </select>
-                            </div>
-
-
                         </div>
                     </div>
                 </div>
-                <div class="col-md-4 mb-4">
-                    <div class="card">
-                        <div class="card-header">
-                            <div class="card-title">
-                                <i class="fas fa-list mr-2"></i>{{__('Server Details')}}
-                            </div>
-                        </div>
-                        <div class="card-body">
 
-                            <ul class="list-group mb-3">
-                                <li x-show="selectedNestObject.name"
-                                    class="list-group-item d-flex justify-content-between lh-condensed">
-                                    <div>
-                                        <h6 class="my-0">{{__('Software / Games')}}</h6>
-                                        <small x-text="selectedNestObject?.name ?? '{{__('No selection')}}'"
-                                               class="text-muted"></small>
-                                    </div>
-                                </li>
-                                <li class="list-group-item d-flex justify-content-between lh-condensed">
-                                    <div>
-                                        <h6 class="my-0">{{__('Specification')}}</h6>
-                                        <small x-text="selectedEggObject?.name ?? '{{__('No selection')}}'"
-                                               class="text-muted"></small>
-                                    </div>
-                                </li>
-                                <li
-                                    class="list-group-item d-flex justify-content-between lh-condensed">
-                                    <div>
-                                        <h6 class="my-0">{{__('Node')}}</h6>
-                                        <small x-text="selectedNodeObject?.name ?? '{{__('No selection')}}'"
-                                               class="text-muted"></small>
+                <div class="w-100"></div>
+                <div class="col" x-show="selectedNode != null">
+                    <div class="row mt-4 justify-content-center">
+                        <template x-for="product in products" :key="product.id">
+                            <div class="card  col-xl-3 col-lg-3 col-md-4 col-sm-10 mr-2 ml-2 ">
+                                <div class="card-body d-flex  flex-column">
+                                    <h4 class="card-title" x-text="product.name"></h4>
+                                    <div class="mt-2">
+                                        <div>
+                                            <p class="card-text text-muted mb-1">{{ __('Resource Data:') }}</p>
+                                            <ul class="pl-0">
+                                                <li class="d-flex justify-content-between">
+                                                    <span class="d-inline-block"><i class="fas fa-microchip"></i>
+                                                        {{ __('CPU') }}</span>
+                                                    <span class=" d-inline-block" x-text="product.cpu + ' %'"></span>
+                                                </li>
+                                                <li class="d-flex justify-content-between">
+                                                    <span class="d-inline-block"><i class="fas fa-memory"></i>
+                                                        {{ __('Memory') }}</span>
+                                                    <span class=" d-inline-block"
+                                                        x-text="product.memory + ' {{ __('MB') }}'"></span>
+                                                </li>
+                                                <li class="d-flex justify-content-between">
+                                                    <div>
+                                                        <i class="fas fa-hdd"></i>
+                                                        <span class="d-inline-block">
+                                                            {{ __('Disk') }}
+                                                        </span>
+                                                    </div>
+                                                    <span class="d-inline-block"
+                                                        x-text="product.disk + ' {{ __('MB') }}'"></span>
+                                                </li>
+                                                <li class="d-flex justify-content-between">
+                                                    <span class="d-inline-block"><i class="fas fa-save"></i>
+                                                        {{ __('Backups') }}</span>
+                                                    <span class=" d-inline-block" x-text="product.backups"></span>
+                                                </li>
+                                                <li class="d-flex justify-content-between">
+                                                    <span class="d-inline-block"><i class="fas fa-database"></i>
+                                                        {{ __('MySQL') }}
+                                                        {{ __('Databases') }}</span>
+                                                    <span class="d-inline-block" x-text="product.databases"></span>
+                                                </li>
+                                                <li class="d-flex justify-content-between">
+                                                    <span class="d-inline-block"><i class="fas fa-network-wired"></i>
+                                                        {{ __('Allocations') }}
+                                                        ({{ __('ports') }})</span>
+                                                    <span class="d-inline-block" x-text="product.allocations"></span>
+                                                </li>
+                                            </ul>
+                                        </div>
+                                        <div class="mt-2 mb-2">
+                                            <span class="card-text text-muted">{{ __('Description') }}</span>
+                                            <p class="card-text" x-text="product.description"></p>
+                                        </div>
                                     </div>
-                                </li>
-                                <li class="list-group-item">
-                                    <div>
-                                        <h6 class="my-0">{{__('Resources')}}</h6>
-                                        <small x-text="selectedProductObject?.name ?? '{{__('No selection')}}'"
-                                               class="text-muted"></small>
+                                    <div class="mt-auto border rounded border-secondary">
+                                        <div class="d-flex justify-content-between p-2">
+                                            <span class="d-inline-block mr-4">
+                                                {{ __('Price') }}:
+                                            </span>
+                                            <span class="d-inline-block"
+                                                x-text="product.price + ' {{ CREDITS_DISPLAY_NAME }}'"></span>
+                                        </div>
                                     </div>
-
-                                    <template x-if="selectedProductObject?.name">
-                                        <ul class="pl-0">
-                                            <li class="d-flex justify-content-between">
-                                                <small class="text-muted d-inline-block">{{__('Cpu')}}</small>
-                                                <small class="text-muted d-inline-block"
-                                                       x-text="selectedProductObject.cpu + ' %'"></small>
-                                            </li>
-                                            <div class="d-flex justify-content-between">
-                                                <small class="text-muted d-inline-block">{{__('Memory')}}</small>
-                                                <small class="text-muted d-inline-block"
-                                                       x-text="selectedProductObject.memory + ' {{__('MB')}}'"></small>
-                                            </div>
-                                            <div class="d-flex justify-content-between">
-                                                <small class="text-muted d-inline-block">{{__('Disk')}}</small>
-                                                <small class="text-muted d-inline-block"
-                                                       x-text="selectedProductObject.disk + ' {{__('MB')}}'"></small>
-                                            </div>
-                                            <div class="d-flex justify-content-between">
-                                                <small class="text-muted d-inline-block">{{__('Databases')}}</small>
-                                                <small class="text-muted d-inline-block"
-                                                       x-text="selectedProductObject.databases + ' {{__('MySQL')}}'"></small>
-                                            </div>
-                                            <div class="d-flex justify-content-between">
-                                                <small class="text-muted d-inline-block">{{__('Backups')}}</small>
-                                                <small class="text-muted d-inline-block"
-                                                       x-text="selectedProductObject.backups"></small>
-                                            </div>
-                                            <div class="d-flex justify-content-between">
-                                               <small class="text-muted d-inline-block">{{__('Allocations')}}</small>
-                                               <small class="text-muted d-inline-block" x-text="selectedProductObject.allocations"></small>
-                                           </div>
-                                        </ul>
-                                    </template>
-
-                                </li>
-                            </ul>
-                            <ul class="list-group mb-3">
-                                <li class="list-group-item d-flex justify-content-between">
-                                    <span>{{CREDITS_DISPLAY_NAME}} {{__('per month')}}</span>
-                                    <strong>
-                                        <i x-show="selectedProductObject?.price" class="fas fa-coins"></i>
-                                        <span x-text="selectedProductObject?.price ?? ''"></span>
-                                    </strong>
-                                </li>
-                            </ul>
-                            <button :disabled="!isFormValid()" :class="isFormValid() ? '' : 'disabled'"
-                                    class="btn btn-primary btn-block">
-                                {{__('Create server')}}
-                            </button>
-                        </div>
+                                    <button type="submit" x-model="selectedProduct" name="product"
+                                        :disabled="product.minimum_credits > user.credits"
+                                        :class="product.minimum_credits > user.credits ? 'disabled' : ''"
+                                        class="btn btn-primary btn-block mt-2" @click="setProduct(product.id)"
+                                        x-text=" product.minimum_credits > user.credits ? '{{ __('Not enough') }} {{ CREDITS_DISPLAY_NAME }}!' : {{ __('Create server') }}">
+                                    </button>
+                                </div>
+                            </div>
                     </div>
+                    </template>
                 </div>
-            </form>
-            <!-- END FORM -->
+        </div>
+
+        </form>
+        <!-- END FORM -->
 
         </div>
     </section>
@@ -314,7 +259,7 @@
                 //values
                 user: {!! $user !!},
                 nests: {!! $nests !!},
-                eggsSave:{!! $eggs !!}, //store back-end eggs
+                eggsSave: {!! $eggs !!}, //store back-end eggs
                 eggs: [],
                 locations: [],
                 products: [],
@@ -346,6 +291,14 @@
                     this.updateSelectedObjects()
                 },
 
+                setProduct(productId) {
+                    if (!productId) return
+
+                    this.selectedProduct = productId;
+                    this.updateSelectedObjects();
+
+                },
+
                 /**
                  * @description fetch all available locations based on the selected egg
                  * @note called whenever a server configuration is selected
@@ -360,7 +313,7 @@
                     this.selectedNode = 'null';
                     this.selectedProduct = 'null';
 
-                    let response = await axios.get(`{{route('products.locations.egg')}}/${this.selectedEgg}`)
+                    let response = await axios.get(`{{ route('products.locations.egg') }}/${this.selectedEgg}`)
                         .catch(console.error)
 
                     this.fetchedLocations = true;
@@ -388,16 +341,14 @@
                     this.products = [];
                     this.selectedProduct = 'null';
 
-                    let response = await axios.get(`{{route('products.products.node')}}/${this.selectedEgg}/${this.selectedNode}`)
+                    let response = await axios.get(
+                            `{{ route('products.products.node') }}/${this.selectedEgg}/${this.selectedNode}`)
                         .catch(console.error)
 
                     this.fetchedProducts = true;
-                    this.products = response.data
+                    // TODO: Sortable by user chosen property (cpu, ram, disk...)
+                    this.products = response.data.sort((p1, p2) => p1.price > p2.price && 1 || -1  )
 
-                    //automatically select the first entry if there is only 1
-                    if (this.products.length === 1) {
-                        this.selectedProduct = this.products[0].id;
-                    }
 
                     this.loading = false;
                     this.updateSelectedObjects()
@@ -414,11 +365,13 @@
                     this.selectedNodeObject = {};
                     this.locations.forEach(location => {
                         if (!this.selectedNodeObject?.id) {
-                            this.selectedNodeObject = location.nodes.find(node => node.id == this.selectedNode) ?? {};
+                            this.selectedNodeObject = location.nodes.find(node => node.id == this.selectedNode) ??
+                                {};
                         }
                     })
 
                     this.selectedProductObject = this.products.find(product => product.id == this.selectedProduct) ?? {}
+                    console.log(this.selectedProduct, this.selectedProductObject, this.products)
                 },
 
                 /**
@@ -436,35 +389,35 @@
                 getNodeInputText() {
                     if (this.fetchedLocations) {
                         if (this.locations.length > 0) {
-                            return '{{__('Please select a node ...')}}';
+                            return '{{ __('Please select a node ...') }}';
                         }
-                        return '{{__('No nodes found matching current configuration')}}'
+                        return '{{ __('No nodes found matching current configuration') }}'
                     }
-                    return '{{__('---')}}';
+                    return '{{ __('---') }}';
                 },
 
                 getProductInputText() {
                     if (this.fetchedProducts) {
                         if (this.products.length > 0) {
-                            return '{{__('Please select a resource ...')}}';
+                            return '{{ __('Please select a resource ...') }}';
                         }
-                        return '{{__('No resources found matching current configuration')}}'
+                        return '{{ __('No resources found matching current configuration') }}'
                     }
-                    return '{{__('---')}}';
+                    return '{{ __('---') }}';
                 },
 
                 getEggInputText() {
                     if (this.selectedNest) {
-                        return '{{__('Please select a configuration ...')}}';
+                        return '{{ __('Please select a configuration ...') }}';
                     }
-                    return '{{__('---')}}';
+                    return '{{ __('---') }}';
                 },
 
                 getProductOptionText(product) {
                     let text = product.name + ' (' + product.description + ')';
 
                     if (product.minimum_credits > this.user.credits) {
-                        return '{{__('Not enough credits!')}} | ' + text;
+                        return '{{ __('Not enough credits!') }} | ' + text;
                     }
 
                     return text;

Неке датотеке нису приказане због велике количине промена