Skip to content

Commit d436e61

Browse files
[6.x] Replace fuse.js with fuzzysort (#11713)
Co-authored-by: Jason Varga <[email protected]>
1 parent 35625c8 commit d436e61

File tree

6 files changed

+42
-49
lines changed

6 files changed

+42
-49
lines changed

package-lock.json

Lines changed: 6 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
"codemirror": "5.65.12",
6161
"cookies-js": "^1.2.2",
6262
"floating-vue": "^5.2.2",
63-
"fuse.js": "^7.0.0",
63+
"fuzzysort": "^3.1.0",
6464
"highlight.js": "^11.7.0",
6565
"imask": "^7.6.1",
6666
"laravel-echo": "^1.16.0",

resources/js/components/data-list/DataList.vue

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script>
2-
import Fuse from 'fuse.js';
2+
import fuzzysort from 'fuzzysort';
33
import { sortBy } from 'lodash-es';
44
55
export default {
@@ -125,14 +125,12 @@ export default {
125125
filterBySearch(rows) {
126126
if (!this.searchQuery) return rows;
127127
128-
const fuse = new Fuse(rows, {
129-
findAllMatches: true,
130-
threshold: 0.1,
131-
minMatchCharLength: 2,
132-
keys: this.searchableColumns,
133-
});
134-
135-
return fuse.search(this.searchQuery).map((result) => result.item);
128+
return fuzzysort
129+
.go(this.searchQuery, rows, {
130+
all: true,
131+
keys: this.searchableColumns,
132+
})
133+
.map((result) => result.obj);
136134
},
137135
138136
sortRows(rows) {

resources/js/components/data-list/FieldFilter.vue

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
<script>
5353
import Validator from '../field-conditions/Validator.js';
5454
import PublishField from '../publish/Field.vue';
55-
import { sortBy } from 'lodash-es';
55+
import { sortBy, mapValues } from 'lodash-es';
5656
import debounce from '@statamic/util/debounce.js';
5757
5858
export default {
@@ -103,20 +103,18 @@ export default {
103103
isFilterComplete() {
104104
if (!this.filter) return false;
105105
106-
let visibleFields = _.chain(this.filter.fields)
107-
.filter(function (field) {
108-
let validator = new Validator(field, this.fieldValues);
109-
return validator.passesConditions();
110-
}, this)
111-
.mapObject((field) => field.handle)
112-
.values()
113-
.value();
106+
let visibleFields = this.filter.fields.filter(function (field) {
107+
let validator = new Validator(field, this.fieldValues);
108+
return validator.passesConditions();
109+
}, this);
110+
111+
visibleFields = mapValues(visibleFields, (field) => field.handle);
112+
visibleFields = Object.values(visibleFields);
114113
115114
let allFieldsFilled =
116-
_.chain(this.fieldValues)
117-
.filter((value, handle) => visibleFields.includes(handle) && value)
118-
.values()
119-
.value().length === visibleFields.length;
115+
Object.entries(this.fieldValues || {}).filter(
116+
([handle, value]) => visibleFields.includes(handle) && value,
117+
).length === visibleFields.length;
120118
121119
return this.field !== null && allFieldsFilled;
122120
},

resources/js/components/data-list/Search.vue

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
type="text"
44
ref="input"
55
:placeholder="__(placeholder)"
6-
:value="value"
6+
:value="modelValue"
77
@input="emitEvent"
88
@keyup.esc="reset"
99
autofocus
@@ -15,26 +15,24 @@
1515
import debounce from '@statamic/util/debounce.js';
1616
1717
export default {
18-
props: ['value'],
19-
2018
props: {
2119
placeholder: {
2220
type: String,
2321
default: 'Search...',
2422
},
25-
value: {
23+
modelValue: {
2624
type: String,
2725
default: '',
2826
},
2927
},
3028
3129
methods: {
3230
emitEvent: debounce(function (event) {
33-
this.$emit('input', event.target.value);
31+
this.$emit('update:model-value', event.target.value);
3432
}, 300),
3533
3634
reset() {
37-
this.$emit('input', '');
35+
this.$emit('update:model-value', '');
3836
},
3937
4038
focus() {

resources/js/components/fields/FieldtypeSelector.vue

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
</template>
7474

7575
<script>
76-
import Fuse from 'fuse.js';
76+
import fuzzysort from 'fuzzysort';
7777
import { ref } from 'vue';
7878
import { mapValues } from 'lodash-es';
7979
const loadedFieldtypes = ref(null);
@@ -198,17 +198,18 @@ export default {
198198
let options = this.allFieldtypes;
199199
200200
if (this.search) {
201-
const fuse = new Fuse(options, {
202-
findAllMatches: true,
203-
threshold: 0.1,
204-
keys: [
205-
{ name: 'text', weight: 1 },
206-
{ name: 'categories', weight: 0.1 },
207-
{ name: 'keywords', weight: 0.4 },
208-
],
209-
});
210-
211-
options = fuse.search(this.search).map((result) => result.item);
201+
return fuzzysort
202+
.go(this.search, this.allFieldtypes, {
203+
all: true,
204+
keys: ['text', (obj) => obj.categories?.join(), (obj) => obj.keywords?.join()],
205+
scoreFn: (scores) => {
206+
const textScore = scores[0]?.score * 1;
207+
const categoriesScore = scores[1]?.score * 0.1;
208+
const keywordsScore = scores[2]?.score * 0.4;
209+
return Math.max(textScore, categoriesScore, keywordsScore);
210+
},
211+
})
212+
.map((result) => result.obj);
212213
}
213214
214215
return options;

0 commit comments

Comments
 (0)