Laravel + Inertiajs + Vuejs + Datatable

Bu çalışmamda Laravel, inertiajs+vuejs ile birlikte bir datatable oluşturmaktı. Görünüm için tailwindcss kullandım.


Yararlandığım kaynaklar, kullandığım paketler:
https://tallpad.com/series/inertiaj…eating-a-datatable-with-laravel-and-inertiajs
https://spatie.be/docs/laravel-query-builder/v5/introduction
https://flatpickr.js.org/


Eklemek istediğiniz, şöyle olsaydı daha iyi olurdu diyebileceğiniz kısımları okumayı isterim.
İyi çalışmalar.

ProjectController.php

PHP:

$data = QueryBuilder::for(Project::class)
    ->defaultSort('-created_at', 'name')
    ->allowedSorts(['name', 'user_id', 'status', 'unit', 'qty', 'created_at'])
    ->allowedFilters([
      'name', 'user_id', 'status', 'unit', 'qty',
      AllowedFilter::scope('start_date'),
      AllowedFilter::scope('end_date'), 'created_at'
    ])
    ->with('user')
    ->paginate(5)
    ->withQueryString();

return Inertia::render('Project/index', [
  'data' => $data,
  'statuses' => ProjectStatuses::all(),
  'units' => Units::all(),
  'filter' => ($request->filter) ? $request->filter : [],
]);

Project.php (Project Model)


PHP:

 public function scopeStartDate(Builder $query, $date): Builder
    {
        return $query->where('start_date', '>=', Carbon::parse($date)->format('Y-m-d H:i'));
    }

    public function scopeEndDate(Builder $query, $date): Builder
    {
        return $query->where('end_date', '<=', Carbon::parse($date)->format('Y-m-d H:i'));
    }

index.vue

//Filtre olarak kullanılan inputlar da aşağıdaki gibi

<!———————— Filtre input ————————>

JavaScript:

<input
    type="text"
class="
      border-gray-300
      focus:border-indigo-300
      focus:ring
      focus:ring-indigo-200
      focus:ring-opacity-50
      rounded-md
      shadow-sm
      py-2
      px-3
      text-xs
      font-medium
    "
name="name"
id="name"
v-model="filters.name"
@keypress="special_form()"
  />


  <flat-pickr
    @on-close="special_form()"
@on-change="special_form()"
class="
      border-gray-300
      focus:border-indigo-300
      focus:ring
      focus:ring-indigo-200
      focus:ring-opacity-50
      rounded-md
      shadow-sm
      py-2
      px-3
      text-xs
      font-medium
    "
v-model="filters.end_date"
:config="config"
  ></flat-pickr>


JavaScript:

export default {
  props: {
    statuses: Object,
    units: Object,
    datas: Object,
    filter: Object,
  },
  data() {
    return {
      filters: {
        name: this.filter.name,
        status: this.filter.status,
        unit: this.filter.unit,
        start_date: this.filter.start_date,
        end_date: this.filter.end_date,
      },
    };
  },
  components: {
    BreezeAuthenticatedLayout,
    Head,
    Link,
    InputText,
    InertiaLink,
    flatPickr,
    Paginator,
  },
  methods: {
    special_form() {
      Object.keys(this.filters).forEach((key) => {
        if (this.filters[key] == "") {
          delete this.filters[key];
        }
      });

      this.$inertia.get(
        route("project_index"),
        {
          filter: this.filters,
        },
        {
          preserveState: true,
          preserveScroll: true,
        }
      );
    }
  }
};