Skip to content

Commit

Permalink
Improve sorting of results when entering text in select fields (stash…
Browse files Browse the repository at this point in the history
…app#4528)

* Sort select results by relevance
* Apply relevance sorting to studio select
* Apply relevance sorting to filter select
  • Loading branch information
WithoutPants authored and dogwithakeyboard committed Feb 18, 2024
1 parent a943d3c commit 727f8fd
Show file tree
Hide file tree
Showing 7 changed files with 412 additions and 51 deletions.
23 changes: 13 additions & 10 deletions ui/v2.5/src/components/List/Filters/PerformersFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useMemo } from "react";
import { PerformersCriterion } from "src/models/list-filter/criteria/performers";
import { useFindPerformersQuery } from "src/core/generated-graphql";
import { ObjectsFilter } from "./SelectableFilter";
import { sortByRelevance } from "src/utils/query";

interface IPerformersFilter {
criterion: PerformersCriterion;
Expand All @@ -18,16 +19,18 @@ function usePerformerQuery(query: string) {
},
});

const results = useMemo(
() =>
data?.findPerformers.performers.map((p) => {
return {
id: p.id,
label: p.name,
};
}) ?? [],
[data]
);
const results = useMemo(() => {
return sortByRelevance(
query,
data?.findPerformers.performers ?? [],
(p) => p.alias_list
).map((p) => {
return {
id: p.id,
label: p.name,
};
});
}, [data, query]);

return { results, loading };
}
Expand Down
23 changes: 13 additions & 10 deletions ui/v2.5/src/components/List/Filters/StudiosFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useMemo } from "react";
import { useFindStudiosQuery } from "src/core/generated-graphql";
import { HierarchicalObjectsFilter } from "./SelectableFilter";
import { StudiosCriterion } from "src/models/list-filter/criteria/studios";
import { sortByRelevance } from "src/utils/query";

interface IStudiosFilter {
criterion: StudiosCriterion;
Expand All @@ -18,16 +19,18 @@ function useStudioQuery(query: string) {
},
});

const results = useMemo(
() =>
data?.findStudios.studios.map((p) => {
return {
id: p.id,
label: p.name,
};
}) ?? [],
[data]
);
const results = useMemo(() => {
return sortByRelevance(
query,
data?.findStudios.studios ?? [],
(s) => s.aliases
).map((p) => {
return {
id: p.id,
label: p.name,
};
});
}, [data, query]);

return { results, loading };
}
Expand Down
23 changes: 13 additions & 10 deletions ui/v2.5/src/components/List/Filters/TagsFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useMemo } from "react";
import { useFindTagsQuery } from "src/core/generated-graphql";
import { HierarchicalObjectsFilter } from "./SelectableFilter";
import { StudiosCriterion } from "src/models/list-filter/criteria/studios";
import { sortByRelevance } from "src/utils/query";

interface ITagsFilter {
criterion: StudiosCriterion;
Expand All @@ -18,16 +19,18 @@ function useTagQuery(query: string) {
},
});

const results = useMemo(
() =>
data?.findTags.tags.map((p) => {
return {
id: p.id,
label: p.name,
};
}) ?? [],
[data]
);
const results = useMemo(() => {
return sortByRelevance(
query,
data?.findTags.tags ?? [],
(t) => t.aliases
).map((p) => {
return {
id: p.id,
label: p.name,
};
});
}, [data, query]);

return { results, loading };
}
Expand Down
7 changes: 6 additions & 1 deletion ui/v2.5/src/components/Performers/PerformerSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
} from "../Shared/FilterSelect";
import { useCompare } from "src/hooks/state";
import { Link } from "react-router-dom";
import { sortByRelevance } from "src/utils/query";

export type SelectObject = {
id: string;
Expand Down Expand Up @@ -59,7 +60,11 @@ export const PerformerSelect: React.FC<
filter.sortBy = "name";
filter.sortDirection = GQL.SortDirectionEnum.Asc;
const query = await queryFindPerformersForSelect(filter);
return query.data.findPerformers.performers.map((performer) => ({
return sortByRelevance(
input,
query.data.findPerformers.performers,
(p) => p.alias_list
).map((performer) => ({
value: performer.id,
object: performer,
}));
Expand Down
21 changes: 11 additions & 10 deletions ui/v2.5/src/components/Studios/StudioSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
} from "../Shared/FilterSelect";
import { useCompare } from "src/hooks/state";
import { Placement } from "react-bootstrap/esm/Overlay";
import { sortByRelevance } from "src/utils/query";

export type SelectObject = {
id: string;
Expand Down Expand Up @@ -62,16 +63,16 @@ export const StudioSelect: React.FC<
filter.sortBy = "name";
filter.sortDirection = GQL.SortDirectionEnum.Asc;
const query = await queryFindStudiosForSelect(filter);
return query.data.findStudios.studios
.filter((studio) => {
// HACK - we should probably exclude these in the backend query, but
// this will do in the short-term
return !exclude.includes(studio.id.toString());
})
.map((studio) => ({
value: studio.id,
object: studio,
}));
let ret = query.data.findStudios.studios.filter((studio) => {
// HACK - we should probably exclude these in the backend query, but
// this will do in the short-term
return !exclude.includes(studio.id.toString());
});

return sortByRelevance(input, ret, (o) => o.aliases).map((studio) => ({
value: studio.id,
object: studio,
}));
}

const StudioOption: React.FC<OptionProps<Option, boolean>> = (
Expand Down
21 changes: 11 additions & 10 deletions ui/v2.5/src/components/Tags/TagSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import { useCompare } from "src/hooks/state";
import { TagPopover } from "./TagPopover";
import { Placement } from "react-bootstrap/esm/Overlay";
import { sortByRelevance } from "src/utils/query";

export type SelectObject = {
id: string;
Expand Down Expand Up @@ -63,16 +64,16 @@ export const TagSelect: React.FC<
filter.sortBy = "name";
filter.sortDirection = GQL.SortDirectionEnum.Asc;
const query = await queryFindTagsForSelect(filter);
return query.data.findTags.tags
.filter((tag) => {
// HACK - we should probably exclude these in the backend query, but
// this will do in the short-term
return !exclude.includes(tag.id.toString());
})
.map((tag) => ({
value: tag.id,
object: tag,
}));
let ret = query.data.findTags.tags.filter((tag) => {
// HACK - we should probably exclude these in the backend query, but
// this will do in the short-term
return !exclude.includes(tag.id.toString());
});

return sortByRelevance(input, ret, (o) => o.aliases).map((tag) => ({
value: tag.id,
object: tag,
}));
}

const TagOption: React.FC<OptionProps<Option, boolean>> = (optionProps) => {
Expand Down

0 comments on commit 727f8fd

Please sign in to comment.