laravel / nova-issues

556 stars 34 forks source link

Custom Filter Vuex Mutation Error: [vuex] unknown mutation type: updateFilterState #5931

Closed HeadStudios closed 1 year ago

HeadStudios commented 1 year ago

Laravel Version: 9 Nova Version: 4.25.1 PHP Version: 8.2 Database Driver & Version: MySQL Operating System and Version: Macbook Browser type and version: Chrome latest Reproduction Repository: https://github.com/HeadStudios/novaissue-5456-nonova

Description:

I'm trying to create a custom filter for Nova using a Vue 3 range slider. The filter is intended to filter records based on a related model's timezone column. However, when I use the filter, I encounter a Vuex error: [vuex] unknown mutation type: updateFilterState.

Detailed steps to reproduce the issue on a fresh Nova installation:

Created a custom filter using the nova:custom-filter Artisan command. Integrated @vueform/slider for Vue 3 as the range slider. Set up the filter to commit the updateFilterState mutation on slider change.

<template>
  <div>
    <Slider v-model="range" @change="handleChange" :min="0" :max="24" />
  </div>
</template>

<script>
import Slider from '@vueform/slider';

export default {
  components: {
      Slider
  },
  props: ['resourceName', 'filterKey', 'currentValue'],
  data() {
      return {
          range: [0, 24] // Default range for 24 hours
      };
  },
  methods: {
      handleChange() {
        this.$store.commit('updateFilterState', {
          filterClass: this.filterKey,
          value: this.range,
      });

          this.$emit('change')
      }
  }
}
</script>

<style src="@vueform/slider/themes/default.css"></style>

<style scoped>
.vue-slider {
    width: 90%; /* Adjust as needed */
    margin: 0 auto; /* Center the slider */
}
</style>
<?php

namespace Kostasmatrix\TimezoneRange;

use Laravel\Nova\Filters\Filter;
use Laravel\Nova\Http\Requests\NovaRequest;

class TimezoneRange extends Filter
{
    /**
     * The filter's component.
     *
     * @var string
     */
    public $component = 'timezone-range';

    /**
     * Apply the filter to the given query.
     *
     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @param  mixed  $value
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function apply(NovaRequest $request, $query, $value)
    {
        // Convert the range values to actual timezones or time offsets
        list($start, $end) = $value;

        // Modify the query to filter based on the related contact's timezone
        return $query->whereHas('contact', function ($query) use ($start, $end) {
            // Get the current time in the contact's timezone
            $query->whereRaw("TIME(CONVERT_TZ(NOW(), 'UTC', timezone)) BETWEEN ? AND ?", [sprintf('%02d:00:00', $start), sprintf('%02d:59:59', $end)]);
        });
    }

    /**
     * Get the filter's available options.
     *
     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
     * @return array
     */
    public function options(NovaRequest $request)
    {
        // Return any necessary options for your filter
        return [];
    }
}

Error: https://p147.p4.n0.cdn.getcloudapp.com/items/7KuX8JKr/6c900876-24f5-4dd6-b52f-90f6372de456.png?v=3de3359831f02feb3fa63b0bf1b2dfc8

Thank you!

milewski commented 1 year ago

The store is namespaced you should do it like this:

this.$store.commit(`${ this.resourceName }/updateFilterState`, {
    filterClass: this.filterKey,
    value: this.range,
});

I have also done a slider filter package if you are interested, perhaps it does exactly what you need: https://github.com/dcasia/nova-slider-filter

HeadStudios commented 1 year ago

The store is namespaced you should do it like this:

this.$store.commit(`${ this.resourceName }/updateFilterState`, {
    filterClass: this.filterKey,
    value: this.range,
});

I have also done a slider filter package if you are interested, perhaps it does exactly what you need: https://github.com/dcasia/nova-slider-filter

Thank you - this has fixed my problem. Appreciated so much - and closing issue now. Cheers