Browse Source

Linking of products to nodes and/or eggs

AVMG20 4 years ago
parent
commit
bd45b3b713

+ 32 - 3
app/Http/Controllers/Admin/ProductController.php

@@ -3,6 +3,10 @@
 namespace App\Http\Controllers\Admin;
 namespace App\Http\Controllers\Admin;
 
 
 use App\Http\Controllers\Controller;
 use App\Http\Controllers\Controller;
+use App\Models\Egg;
+use App\Models\Location;
+use App\Models\Nest;
+use App\Models\Node;
 use App\Models\Product;
 use App\Models\Product;
 use Exception;
 use Exception;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\Foundation\Application;
@@ -32,7 +36,10 @@ class ProductController extends Controller
      */
      */
     public function create()
     public function create()
     {
     {
-        return view('admin.products.create');
+        return view('admin.products.create' , [
+            'locations' => Location::with('nodes')->get(),
+            'nests' => Nest::with('eggs')->get(),
+        ]);
     }
     }
 
 
     /**
     /**
@@ -55,11 +62,17 @@ class ProductController extends Controller
             "databases" => "required|numeric|max:1000000|min:0",
             "databases" => "required|numeric|max:1000000|min:0",
             "backups" => "required|numeric|max:1000000|min:0",
             "backups" => "required|numeric|max:1000000|min:0",
             "allocations" => "required|numeric|max:1000000|min:0",
             "allocations" => "required|numeric|max:1000000|min:0",
+            "nodes.*" => "required|exists:nodes,id",
+            "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
             "disabled" => "nullable",
         ]);
         ]);
 
 
         $disabled = !is_null($request->input('disabled'));
         $disabled = !is_null($request->input('disabled'));
-        Product::create(array_merge($request->all(), ['disabled' => $disabled]));
+        $product = Product::create(array_merge($request->all(), ['disabled' => $disabled]));
+
+        #link nodes and eggs
+        $product->eggs()->attach($request->input('eggs'));
+        $product->nodes()->attach($request->input('nodes'));
 
 
         return redirect()->route('admin.products.index')->with('success', 'product has been created!');
         return redirect()->route('admin.products.index')->with('success', 'product has been created!');
     }
     }
@@ -86,7 +99,9 @@ class ProductController extends Controller
     public function edit(Product $product)
     public function edit(Product $product)
     {
     {
         return view('admin.products.edit', [
         return view('admin.products.edit', [
-            'product' => $product
+            'product' => $product,
+            'locations' => Location::with('nodes')->get(),
+            'nests' => Nest::with('eggs')->get(),
         ]);
         ]);
     }
     }
 
 
@@ -111,12 +126,20 @@ class ProductController extends Controller
             "databases" => "required|numeric|max:1000000|min:0",
             "databases" => "required|numeric|max:1000000|min:0",
             "backups" => "required|numeric|max:1000000|min:0",
             "backups" => "required|numeric|max:1000000|min:0",
             "allocations" => "required|numeric|max:1000000|min:0",
             "allocations" => "required|numeric|max:1000000|min:0",
+            "nodes.*" => "required|exists:nodes,id",
+            "eggs.*" => "required|exists:eggs,id",
             "disabled" => "nullable",
             "disabled" => "nullable",
         ]);
         ]);
 
 
         $disabled = !is_null($request->input('disabled'));
         $disabled = !is_null($request->input('disabled'));
         $product->update(array_merge($request->all(), ['disabled' => $disabled]));
         $product->update(array_merge($request->all(), ['disabled' => $disabled]));
 
 
+        #link nodes and eggs
+        $product->eggs()->detach();
+        $product->nodes()->detach();
+        $product->eggs()->attach($request->input('eggs'));
+        $product->nodes()->attach($request->input('nodes'));
+
         return redirect()->route('admin.products.index')->with('success', 'product has been updated!');
         return redirect()->route('admin.products.index')->with('success', 'product has been updated!');
     }
     }
 
 
@@ -174,6 +197,12 @@ class ProductController extends Controller
             ->addColumn('servers', function (Product $product) {
             ->addColumn('servers', function (Product $product) {
                 return $product->servers()->count();
                 return $product->servers()->count();
             })
             })
+            ->addColumn('nodes', function (Product $product) {
+                return $product->nodes()->count();
+            })
+            ->addColumn('eggs', function (Product $product) {
+                return $product->eggs()->count();
+            })
             ->addColumn('disabled', function (Product $product) {
             ->addColumn('disabled', function (Product $product) {
                 $checked = $product->disabled == false ? "checked" : "";
                 $checked = $product->disabled == false ? "checked" : "";
                 return '
                 return '

+ 5 - 0
app/Http/Controllers/HomeController.php

@@ -2,6 +2,8 @@
 
 
 namespace App\Http\Controllers;
 namespace App\Http\Controllers;
 
 
+use App\Models\Egg;
+use App\Models\Product;
 use App\Models\UsefulLink;
 use App\Models\UsefulLink;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Auth;
@@ -16,6 +18,9 @@ class HomeController extends Controller
     /** Show the application dashboard. */
     /** Show the application dashboard. */
     public function index(Request $request)
     public function index(Request $request)
     {
     {
+
+        dd(Product::first()->nodes()->get() , Product::first()->eggs()->get());
+
         $usage = 0;
         $usage = 0;
 
 
         foreach (Auth::user()->servers as $server){
         foreach (Auth::user()->servers as $server){

+ 23 - 14
app/Models/Egg.php

@@ -6,6 +6,7 @@ use App\Classes\Pterodactyl;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
 
 class Egg extends Model
 class Egg extends Model
 {
 {
@@ -23,14 +24,6 @@ class Egg extends Model
         'environment',
         'environment',
     ];
     ];
 
 
-    /**
-     * @return BelongsTo
-     */
-    public function nest()
-    {
-        return $this->belongsTo(Nest::class, 'id', 'nest_id');
-    }
-
     /**
     /**
      * @return array
      * @return array
      */
      */
@@ -39,7 +32,7 @@ class Egg extends Model
         $array = [];
         $array = [];
 
 
         foreach (json_decode($this->environment) as $variable) {
         foreach (json_decode($this->environment) as $variable) {
-            foreach ($variable as $key => $value){
+            foreach ($variable as $key => $value) {
                 $array[$key] = $value;
                 $array[$key] = $value;
             }
             }
         }
         }
@@ -47,12 +40,13 @@ class Egg extends Model
         return $array;
         return $array;
     }
     }
 
 
-    public static function syncEggs(){
+    public static function syncEggs()
+    {
 
 
-         Nest::all()->each(function (Nest $nest) {
+        Nest::all()->each(function (Nest $nest) {
             $eggs = Pterodactyl::getEggs($nest);
             $eggs = Pterodactyl::getEggs($nest);
 
 
-            foreach ($eggs as $egg){
+            foreach ($eggs as $egg) {
                 $array = [];
                 $array = [];
                 $environment = [];
                 $environment = [];
 
 
@@ -64,17 +58,32 @@ class Egg extends Model
                 $array['startup'] = $egg['attributes']['startup'];
                 $array['startup'] = $egg['attributes']['startup'];
 
 
                 //get environment variables
                 //get environment variables
-                foreach ($egg['attributes']['relationships']['variables']['data'] as $variable){
+                foreach ($egg['attributes']['relationships']['variables']['data'] as $variable) {
                     $environment[$variable['attributes']['env_variable']] = $variable['attributes']['default_value'];
                     $environment[$variable['attributes']['env_variable']] = $variable['attributes']['default_value'];
                 }
                 }
 
 
                 $array['environment'] = json_encode([$environment]);
                 $array['environment'] = json_encode([$environment]);
 
 
-                self::firstOrCreate(['id' => $array['id']] , $array);
+                self::firstOrCreate(['id' => $array['id']], $array);
             }
             }
 
 
         });
         });
+    }
 
 
+    /**
+     * @return BelongsTo
+     */
+    public function nest()
+    {
+        return $this->belongsTo(Nest::class, 'id', 'nest_id');
+    }
 
 
+    /**
+     * @return BelongsToMany
+     */
+    public function products()
+    {
+        return $this->belongsToMany(Product::class);
     }
     }
+
 }
 }

+ 9 - 0
app/Models/Node.php

@@ -7,6 +7,7 @@ use Exception;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
 
 class Node extends Model
 class Node extends Model
 {
 {
@@ -48,4 +49,12 @@ class Node extends Model
         }
         }
 
 
     }
     }
+
+    /**
+     * @return BelongsToMany
+     */
+    public function products()
+    {
+        return $this->belongsToMany(Product::class);
+    }
 }
 }

+ 21 - 1
app/Models/Product.php

@@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 use Illuminate\Database\Eloquent\Relations\BelongsToMany;
+use Illuminate\Database\Eloquent\Relations\HasMany;
 use Spatie\Activitylog\Traits\LogsActivity;
 use Spatie\Activitylog\Traits\LogsActivity;
 
 
 class Product extends Model
 class Product extends Model
@@ -25,6 +26,11 @@ class Product extends Model
 
 
             $product->{$product->getKeyName()} = $client->generateId($size = 21);
             $product->{$product->getKeyName()} = $client->generateId($size = 21);
         });
         });
+
+        static::deleting(function(Product $product) {
+            $product->nodes()->detach();
+            $product->eggs()->detach();
+        });
     }
     }
 
 
     public function getHourlyPrice()
     public function getHourlyPrice()
@@ -45,8 +51,22 @@ class Product extends Model
     /**
     /**
      * @return BelongsTo
      * @return BelongsTo
      */
      */
-    public function servers(): BelongsTo
+    public function servers()
     {
     {
         return $this->belongsTo(Server::class , 'id' , 'product_id');
         return $this->belongsTo(Server::class , 'id' , 'product_id');
     }
     }
+
+    /**
+     * @return BelongsToMany
+     */
+    public function eggs() {
+        return $this->belongsToMany(Egg::class);
+    }
+
+    /**
+     * @return BelongsToMany
+     */
+    public function nodes() {
+        return $this->belongsToMany(Node::class);
+    }
 }
 }

+ 32 - 0
database/migrations/2021_07_06_152319_create_egg_product_table.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateEggProductTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('egg_product', function (Blueprint $table) {
+            $table->foreignId('egg_id')->constrained();
+            $table->foreignUuid('product_id')->constrained();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('egg_product');
+    }
+}

+ 32 - 0
database/migrations/2021_07_06_154314_create_node_product_table.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateNodeProductTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('node_product', function (Blueprint $table) {
+            $table->foreignId('node_id')->constrained();
+            $table->foreignUuid('product_id')->constrained();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('node_product');
+    }
+}

+ 32 - 0
database/migrations/2021_07_06_154658_add_disabled_to_eggs_table.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddDisabledToEggsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('eggs', function (Blueprint $table) {
+            $table->boolean('disabled')->default(false);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('eggs', function (Blueprint $table) {
+            $table->dropColumn('disabled');
+        });
+    }
+}

+ 86 - 12
resources/views/admin/products/create.blade.php

@@ -24,17 +24,24 @@
     <!-- MAIN CONTENT -->
     <!-- MAIN CONTENT -->
     <section class="content">
     <section class="content">
         <div class="container-fluid">
         <div class="container-fluid">
+            <form action="{{route('admin.products.store')}}" method="POST">
+                @csrf
+                <div class="row">
+                    <div class="col-lg-6">
+                        <div class="card">
+                            <div class="card-header">
+                                <h5 class="card-title">Product Details</h5>
+                            </div>
+                            <div class="card-body">
 
 
-            <div class="row">
-                <div class="col-lg-6">
-                    <div class="card">
-                        <div class="card-body">
-                            <form action="{{route('admin.products.store')}}" method="POST">
-                                @csrf
                                 <div class="d-flex flex-row-reverse">
                                 <div class="d-flex flex-row-reverse">
                                     <div class="custom-control custom-switch">
                                     <div class="custom-control custom-switch">
-                                        <input type="checkbox" name="disabled" class="custom-control-input custom-control-input-danger" id="switch1">
-                                        <label class="custom-control-label" for="switch1">Disabled <i data-toggle="popover" data-trigger="hover" data-content="Will hide this option from being selected" class="fas fa-info-circle"></i></label>
+                                        <input type="checkbox" name="disabled"
+                                               class="custom-control-input custom-control-input-danger" id="switch1">
+                                        <label class="custom-control-label" for="switch1">Disabled <i
+                                                data-toggle="popover" data-trigger="hover"
+                                                data-content="Will hide this option from being selected"
+                                                class="fas fa-info-circle"></i></label>
                                     </div>
                                     </div>
                                 </div>
                                 </div>
 
 
@@ -105,7 +112,10 @@
                                         </div>
                                         </div>
 
 
                                         <div class="form-group">
                                         <div class="form-group">
-                                            <label for="description">Description <i data-toggle="popover" data-trigger="hover" data-content="This is what the users sees" class="fas fa-info-circle"></i></label>
+                                            <label for="description">Description <i data-toggle="popover"
+                                                                                    data-trigger="hover"
+                                                                                    data-content="This is what the users sees"
+                                                                                    class="fas fa-info-circle"></i></label>
                                             <textarea id="description" name="description"
                                             <textarea id="description" name="description"
                                                       type="text"
                                                       type="text"
                                                       class="form-control @error('description') is-invalid @enderror"
                                                       class="form-control @error('description') is-invalid @enderror"
@@ -190,16 +200,80 @@
                                         Submit
                                         Submit
                                     </button>
                                     </button>
                                 </div>
                                 </div>
-                            </form>
+
+                            </div>
                         </div>
                         </div>
                     </div>
                     </div>
+
+                    <div class="col-lg-6">
+                        <div class="card">
+                            <div class="card-header">
+                                <h5 class="card-title">Product Linking <i data-toggle="popover" data-trigger="hover"
+                                                                          data-content="Linked products will only be available when the user has selected the linked node and/or egg"
+                                                                          class="fas fa-info-circle"></i></h5>
+                            </div>
+                            <div class="card-body">
+
+                                <div class="form-group">
+                                    <label for="nodes">Nodes</label>
+                                    <select id="nodes" class="custom-select @error('nodes') is-invalid @enderror"
+                                            name="nodes[]" multiple="multiple" autocomplete="off">
+                                        @foreach($locations as $location)
+                                            <optgroup label="{{$location->name}}">
+                                                @foreach($location->nodes as $node)
+                                                    <option value="{{$node->id}}">{{$node->name}}</option>
+                                                @endforeach
+                                            </optgroup>
+                                        @endforeach
+                                    </select>
+                                    @error('nodes')
+                                    <div class="text-danger">
+                                        {{$message}}
+                                    </div>
+                                    @enderror
+                                    <div class="text-muted">
+                                        This product will only be available for these nodes
+                                    </div>
+                                </div>
+
+
+                                <div class="form-group">
+                                    <label for="eggs">Eggs</label>
+                                    <select id="eggs" class="custom-select @error('eggs') is-invalid @enderror"
+                                            name="eggs[]" multiple="multiple" autocomplete="off">
+                                        @foreach($nests as $nest)
+                                            <optgroup label="{{$nest->name}}">
+                                                @foreach($nest->eggs as $egg)
+                                                    <option value="{{$egg->id}}">{{$egg->name}}</option>
+                                                @endforeach
+                                            </optgroup>
+                                        @endforeach
+                                    </select>
+                                    @error('eggs')
+                                    <div class="text-danger">
+                                        {{$message}}
+                                    </div>
+                                    @enderror
+                                    <div class="text-muted">
+                                        This product will only be available for these eggs
+                                    </div>
+                                </div>
+
+                            </div>
+                        </div>
+                    </div>
+
                 </div>
                 </div>
-            </div>
+            </form>
 
 
         </div>
         </div>
     </section>
     </section>
     <!-- END CONTENT -->
     <!-- END CONTENT -->
 
 
-
+    <script>
+        document.addEventListener('DOMContentLoaded', (event) => {
+            $('.custom-select').select2();
+        })
+    </script>
 
 
 @endsection
 @endsection

+ 101 - 21
resources/views/admin/products/edit.blade.php

@@ -12,7 +12,8 @@
                     <ol class="breadcrumb float-sm-right">
                     <ol class="breadcrumb float-sm-right">
                         <li class="breadcrumb-item"><a href="{{route('home')}}">Dashboard</a></li>
                         <li class="breadcrumb-item"><a href="{{route('home')}}">Dashboard</a></li>
                         <li class="breadcrumb-item"><a href="{{route('admin.products.index')}}">Products</a></li>
                         <li class="breadcrumb-item"><a href="{{route('admin.products.index')}}">Products</a></li>
-                        <li class="breadcrumb-item"><a class="text-muted" href="{{route('admin.products.edit' , $product->id)}}">Edit</a>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                                       href="{{route('admin.products.edit' , $product->id)}}">Edit</a>
                         </li>
                         </li>
                     </ol>
                     </ol>
                 </div>
                 </div>
@@ -24,32 +25,42 @@
     <!-- MAIN CONTENT -->
     <!-- MAIN CONTENT -->
     <section class="content">
     <section class="content">
         <div class="container-fluid">
         <div class="container-fluid">
+            <form action="{{route('admin.products.update' , $product->id)}}" method="POST">
+                @csrf
+                @method('PATCH')
 
 
+                <div class="row">
+                    <div class="col-lg-6">
 
 
-            <div class="row">
-                <div class="col-lg-6">
+                        @if($product->servers()->count() > 0)
+                            <div class="callout callout-danger">
+                                <h4>Editing the resource options will not automatically update the servers on
+                                    pterodactyl's side!</h4>
+                                <p class="text-muted">Automatically updating resource options on pterodactyl side is on
+                                    my todo list :)</p>
+                            </div>
+                        @endif
 
 
-                    @if($product->servers()->count() > 0)
-                        <div class="callout callout-danger">
-                            <h4>Editing the resource options will not automatically update the servers on pterodactyl's side!</h4>
-                            <p class="text-muted">Automatically updating resource options on pterodactyl side is on my todo list :)</p>
-                        </div>
-                    @endif
+                        <div class="card">
+                            <div class="card-header">
+                                <h5 class="card-title">Product Details</h5>
+                            </div>
+                            <div class="card-body">
 
 
-                    <div class="card">
-                        <div class="card-body">
-                            <form action="{{route('admin.products.update' , $product->id)}}" method="POST">
-                                @csrf
-                                @method('PATCH')
                                 <div class="d-flex flex-row-reverse">
                                 <div class="d-flex flex-row-reverse">
                                     <div class="custom-control custom-switch">
                                     <div class="custom-control custom-switch">
-                                        <input type="checkbox" @if($product->disabled) checked @endif name="disabled" class="custom-control-input custom-control-input-danger" id="switch1">
-                                        <label class="custom-control-label" for="switch1">Disabled <i data-toggle="popover" data-trigger="hover" data-content="Will hide this option from being selected" class="fas fa-info-circle"></i></label>
+                                        <input type="checkbox" @if($product->disabled) checked @endif name="disabled"
+                                               class="custom-control-input custom-control-input-danger" id="switch1">
+                                        <label class="custom-control-label" for="switch1">Disabled <i
+                                                data-toggle="popover" data-trigger="hover"
+                                                data-content="Will hide this option from being selected"
+                                                class="fas fa-info-circle"></i></label>
                                     </div>
                                     </div>
                                 </div>
                                 </div>
 
 
                                 <div class="row">
                                 <div class="row">
                                     <div class="col-lg-6">
                                     <div class="col-lg-6">
+
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="name">Name</label>
                                             <label for="name">Name</label>
                                             <input value="{{$product->name}}" id="name" name="name" type="text"
                                             <input value="{{$product->name}}" id="name" name="name" type="text"
@@ -115,7 +126,10 @@
                                         </div>
                                         </div>
 
 
                                         <div class="form-group">
                                         <div class="form-group">
-                                            <label for="description">Description <i data-toggle="popover" data-trigger="hover" data-content="This is what the users sees" class="fas fa-info-circle"></i></label>
+                                            <label for="description">Description <i data-toggle="popover"
+                                                                                    data-trigger="hover"
+                                                                                    data-content="This is what the users sees"
+                                                                                    class="fas fa-info-circle"></i></label>
                                             <textarea id="description" name="description"
                                             <textarea id="description" name="description"
                                                       type="text"
                                                       type="text"
                                                       class="form-control @error('description') is-invalid @enderror"
                                                       class="form-control @error('description') is-invalid @enderror"
@@ -200,16 +214,82 @@
                                         Submit
                                         Submit
                                     </button>
                                     </button>
                                 </div>
                                 </div>
-                            </form>
+
+                            </div>
                         </div>
                         </div>
                     </div>
                     </div>
-                </div>
-            </div>
 
 
+                    <div class="col-lg-6">
+                        <div class="card">
+                            <div class="card-header">
+                                <h5 class="card-title">Product Linking <i data-toggle="popover" data-trigger="hover"
+                                                                          data-content="Linked products will only be available when the user has selected the linked node and/or egg"
+                                                                          class="fas fa-info-circle"></i></h5>
+                            </div>
+                            <div class="card-body">
+
+                                <div class="form-group">
+                                    <label for="nodes">Nodes</label>
+                                    <select id="nodes" style="width:100%"
+                                            class="custom-select @error('nodes') is-invalid @enderror" name="nodes[]"
+                                            multiple="multiple" autocomplete="off">
+                                        @foreach($locations as $location)
+                                            <optgroup label="{{$location->name}}">
+                                                @foreach($location->nodes as $node)
+                                                    <option @if($product->nodes->contains('id' , $node->id)) selected
+                                                            @endif value="{{$node->id}}">{{$node->name}}</option>
+                                                @endforeach
+                                            </optgroup>
+                                        @endforeach
+                                    </select>
+                                    @error('nodes')
+                                    <div class="text-danger">
+                                        {{$message}}
+                                    </div>
+                                    @enderror
+                                    <div class="text-muted">
+                                        This product will only be available for these nodes
+                                    </div>
+                                </div>
+
+                                <div class="form-group">
+                                    <label for="eggs">Eggs</label>
+                                    <select id="eggs" style="width:100%"
+                                            class="custom-select @error('eggs') is-invalid @enderror" name="eggs[]"
+                                            multiple="multiple" autocomplete="off">
+                                        @foreach($nests as $nest)
+                                            <optgroup label="{{$nest->name}}">
+                                                @foreach($nest->eggs as $egg)
+                                                    <option @if($product->eggs->contains('id' , $egg->id)) selected
+                                                            @endif value="{{$egg->id}}">{{$egg->name}}</option>
+                                                @endforeach
+                                            </optgroup>
+                                        @endforeach
+                                    </select>
+                                    @error('eggs')
+                                    <div class="text-danger">
+                                        {{$message}}
+                                    </div>
+                                    @enderror
+                                    <div class="text-muted">
+                                        This product will only be available for these eggs
+                                    </div>
+                                </div>
+
+                            </div>
+                        </div>
+                    </div>
+
+                </div>
+            </form>
         </div>
         </div>
     </section>
     </section>
     <!-- END CONTENT -->
     <!-- END CONTENT -->
 
 
-
+    <script>
+        document.addEventListener('DOMContentLoaded', (event) => {
+            $('.custom-select').select2();
+        })
+    </script>
 
 
 @endsection
 @endsection

+ 5 - 4
resources/views/admin/products/index.blade.php

@@ -46,10 +46,10 @@
                             <th>Cpu</th>
                             <th>Cpu</th>
                             <th>Swap</th>
                             <th>Swap</th>
                             <th>Disk</th>
                             <th>Disk</th>
-                            <th>IO</th>
                             <th>Databases</th>
                             <th>Databases</th>
                             <th>Backups</th>
                             <th>Backups</th>
-                            <th>Allocations</th>
+                            <th>Eggs</th>
+                            <th>Nodes</th>
                             <th>Servers</th>
                             <th>Servers</th>
                             <th>Created at</th>
                             <th>Created at</th>
                             <th></th>
                             <th></th>
@@ -79,6 +79,7 @@
                 processing: true,
                 processing: true,
                 serverSide: true,
                 serverSide: true,
                 stateSave: true,
                 stateSave: true,
+                order: [[ 2, "asc" ]],
                 ajax: "{{route('admin.products.datatable')}}",
                 ajax: "{{route('admin.products.datatable')}}",
                 columns: [
                 columns: [
                     {data: 'disabled'},
                     {data: 'disabled'},
@@ -88,10 +89,10 @@
                     {data: 'cpu'},
                     {data: 'cpu'},
                     {data: 'swap'},
                     {data: 'swap'},
                     {data: 'disk'},
                     {data: 'disk'},
-                    {data: 'io'},
                     {data: 'databases'},
                     {data: 'databases'},
                     {data: 'backups'},
                     {data: 'backups'},
-                    {data: 'allocations'},
+                    {data: 'nodes', sortable: false},
+                    {data: 'eggs', sortable: false},
                     {data: 'servers', sortable: false},
                     {data: 'servers', sortable: false},
                     {data: 'created_at'},
                     {data: 'created_at'},
                     {data: 'actions', sortable: false},
                     {data: 'actions', sortable: false},

+ 5 - 0
resources/views/layouts/main.blade.php

@@ -16,6 +16,9 @@
     {{--  summernote --}}
     {{--  summernote --}}
     <link rel="stylesheet" href="{{asset('plugins/summernote/summernote-bs4.min.css')}}">
     <link rel="stylesheet" href="{{asset('plugins/summernote/summernote-bs4.min.css')}}">
 
 
+    {{--  select2 --}}
+    <link rel="stylesheet" href="{{asset('plugins/select2/css/select2.min.css')}}">
+
     <link rel="stylesheet" href="{{asset('css/app.css')}}">
     <link rel="stylesheet" href="{{asset('css/app.css')}}">
     <link rel="preload" href="{{asset('plugins/fontawesome-free/css/all.min.css')}}" as="style"
     <link rel="preload" href="{{asset('plugins/fontawesome-free/css/all.min.css')}}" as="style"
           onload="this.onload=null;this.rel='stylesheet'">
           onload="this.onload=null;this.rel='stylesheet'">
@@ -315,6 +318,8 @@
 <script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.24/datatables.min.js"></script>
 <script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.24/datatables.min.js"></script>
 <!-- Summernote -->
 <!-- Summernote -->
 <script src="{{asset('plugins/summernote/summernote-bs4.min.js')}}"></script>
 <script src="{{asset('plugins/summernote/summernote-bs4.min.js')}}"></script>
+<!-- select2 -->
+<script src="{{asset('plugins/select2/js/select2.min.js')}}"></script>
 
 
 <script>
 <script>
     $(document).ready(function () {
     $(document).ready(function () {