Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI filter refactor #1406

Merged
merged 28 commits into from
May 31, 2021
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0e77314
Refactor Criterion
WithoutPants Apr 9, 2021
70b5986
Separate filter options from filter
WithoutPants Apr 22, 2021
5d336b9
Refactoring
WithoutPants Apr 23, 2021
b8d1f97
More refactoring
WithoutPants Apr 23, 2021
26488e4
Rename utils to factory
WithoutPants Apr 23, 2021
b1bfde9
Format
WithoutPants Apr 23, 2021
e0f508d
Apply factory rename
WithoutPants Apr 23, 2021
1129d20
Missing commit
WithoutPants Apr 23, 2021
15efd73
Fix rebase errors
WithoutPants May 19, 2021
aad80b9
Refactoring
WithoutPants May 19, 2021
2ff1b6e
Bug fixes
WithoutPants May 19, 2021
20d22e5
Sort sort by options by alphabetical
WithoutPants May 19, 2021
497a32b
Refactor criterion options
WithoutPants May 19, 2021
fbb0f9d
Simplify list filter options
WithoutPants May 19, 2021
777f081
Refactor i8n
WithoutPants May 20, 2021
2725686
i8n refactoring
WithoutPants May 20, 2021
7e97563
Fix indentation
WithoutPants May 20, 2021
7c4cda9
Clean up
WithoutPants May 20, 2021
b66fbf2
Remove incorrect comment
WithoutPants May 20, 2021
fc0a752
Fix circular import
WithoutPants May 20, 2021
41113cf
Sort zh-TW
WithoutPants May 20, 2021
4e17a5f
Format
WithoutPants May 20, 2021
4b7637d
Merge remote-tracking branch 'upstream/develop' into filter-refactor
WithoutPants May 25, 2021
d4fa4dc
Simplify ILabeledIdCriterion
WithoutPants May 25, 2021
ae3a596
Fix parent studios criterion
WithoutPants May 25, 2021
4c773eb
Tidying
WithoutPants May 31, 2021
31921f0
Merge remote-tracking branch 'upstream/develop' into filter-refactor
WithoutPants May 31, 2021
a2260e6
Add changelog entry
WithoutPants May 31, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions ui/v2.5/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,27 @@ const intlFormats = {
},
};

function languageMessageString(language: string) {
return language.replace(/-/, "");
}

export const App: React.FC = () => {
const config = useConfiguration();
const { data: systemStatusData } = useSystemStatus();
const language = config.data?.configuration?.interface?.language ?? "en-GB";
const messageLanguage = language.replace(/-/, "");
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const messages = flattenMessages((locales as any)[messageLanguage]);
const defaultLocale = "en-GB";
const language =
config.data?.configuration?.interface?.language ?? defaultLocale;
const defaultMessageLanguage = languageMessageString(defaultLocale);
const messageLanguage = languageMessageString(language);

// use en-GB as default messages if any messages aren't found in the chosen language
const mergedMessages = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...(locales as any)[defaultMessageLanguage],
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...(locales as any)[messageLanguage],
};
const messages = flattenMessages(mergedMessages);

const setupMatch = useRouteMatch(["/setup", "/migrate"]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const GalleryAddPanel: React.FC<IGalleryAddProps> = ({ gallery }) => {
};
// if galleries is already present, then we modify it, otherwise add
let galleryCriterion = filter.criteria.find((c) => {
return c.type === "galleries";
return c.criterionOption.value === "galleries";
}) as GalleriesCriterion;

if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const GalleryImagesPanel: React.FC<IGalleryDetailsProps> = ({
};
// if galleries is already present, then we modify it, otherwise add
let galleryCriterion = filter.criteria.find((c) => {
return c.type === "galleries";
return c.criterionOption.value === "galleries";
}) as GalleriesCriterion;

if (
Expand Down
61 changes: 41 additions & 20 deletions ui/v2.5/src/components/List/AddFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@ import { Icon, FilterSelect, DurationInput } from "src/components/Shared";
import { CriterionModifier } from "src/core/generated-graphql";
import {
Criterion,
CriterionType,
DurationCriterion,
CriterionValue,
} from "src/models/list-filter/criteria/criterion";
import { NoneCriterion } from "src/models/list-filter/criteria/none";
import { makeCriteria } from "src/models/list-filter/criteria/utils";
import { ListFilterModel } from "src/models/list-filter/filter";
import { makeCriteria } from "src/models/list-filter/criteria/factory";
import { ListFilterOptions } from "src/models/list-filter/filter-options";
import { useIntl } from "react-intl";
import { CriterionType } from "src/models/list-filter/types";

interface IAddFilterProps {
onAddCriterion: (criterion: Criterion, oldId?: string) => void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onAddCriterion: (criterion: Criterion<any>, oldId?: string) => void;
onCancel: () => void;
filter: ListFilterModel;
editingCriterion?: Criterion;
filterOptions: ListFilterOptions;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
editingCriterion?: Criterion<any>;
}

export const AddFilter: React.FC<IAddFilterProps> = (
Expand All @@ -27,10 +30,15 @@ export const AddFilter: React.FC<IAddFilterProps> = (
const defaultValue = useRef<string | number | undefined>();

const [isOpen, setIsOpen] = useState(false);
const [criterion, setCriterion] = useState<Criterion>(new NoneCriterion());
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const [criterion, setCriterion] = useState<Criterion<any>>(
new NoneCriterion()
);

const valueStage = useRef<CriterionValue>(criterion.value);

const intl = useIntl();

// configure keyboard shortcuts
useEffect(() => {
Mousetrap.bind("f", () => setIsOpen(true));
Expand Down Expand Up @@ -114,7 +122,7 @@ export const AddFilter: React.FC<IAddFilterProps> = (
}

const maybeRenderFilterPopoverContents = () => {
if (criterion.type === "none") {
if (criterion.criterionOption.value === "none") {
return;
}

Expand Down Expand Up @@ -149,19 +157,19 @@ export const AddFilter: React.FC<IAddFilterProps> = (

if (Array.isArray(criterion.value)) {
if (
criterion.type !== "performers" &&
criterion.type !== "studios" &&
criterion.type !== "parent_studios" &&
criterion.type !== "tags" &&
criterion.type !== "sceneTags" &&
criterion.type !== "performerTags" &&
criterion.type !== "movies"
criterion.criterionOption.value !== "performers" &&
criterion.criterionOption.value !== "studios" &&
criterion.criterionOption.value !== "parent_studios" &&
criterion.criterionOption.value !== "tags" &&
criterion.criterionOption.value !== "sceneTags" &&
criterion.criterionOption.value !== "performerTags" &&
criterion.criterionOption.value !== "movies"
)
return;

return (
<FilterSelect
type={criterion.type}
type={criterion.criterionOption.value}
isMulti
onSelect={(items) => {
const newCriterion = _.cloneDeep(criterion);
Expand Down Expand Up @@ -223,18 +231,28 @@ export const AddFilter: React.FC<IAddFilterProps> = (
if (props.editingCriterion) {
return;
}

const options = props.filterOptions.criterionOptions
.map((c) => {
return {
value: c.value,
text: intl.formatMessage({ id: c.messageID }),
};
})
.sort((a, b) => a.text.localeCompare(b.text));

return (
<Form.Group controlId="filter">
<Form.Label>Filter</Form.Label>
<Form.Control
as="select"
onChange={onChangedCriteriaType}
value={criterion.type}
value={criterion.criterionOption.value}
className="btn-secondary"
>
{props.filter.criterionOptions.map((c) => (
{options.map((c) => (
<option key={c.value} value={c.value}>
{c.label}
{c.text}
</option>
))}
</Form.Control>
Expand Down Expand Up @@ -263,7 +281,10 @@ export const AddFilter: React.FC<IAddFilterProps> = (
</div>
</Modal.Body>
<Modal.Footer>
<Button onClick={onAddFilter} disabled={criterion.type === "none"}>
<Button
onClick={onAddFilter}
disabled={criterion.criterionOption.value === "none"}
>
{title}
</Button>
</Modal.Footer>
Expand Down
69 changes: 46 additions & 23 deletions ui/v2.5/src/components/List/ListFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { Criterion } from "src/models/list-filter/criteria/criterion";
import { ListFilterModel } from "src/models/list-filter/filter";
import { DisplayMode } from "src/models/list-filter/types";
import { useFocus } from "src/utils";
import { ListFilterOptions } from "src/models/list-filter/filter-options";
import { useIntl } from "react-intl";
import { AddFilter } from "./AddFilter";

interface IListFilterOperation {
Expand All @@ -38,6 +40,7 @@ interface IListFilterProps {
onDelete?: () => void;
otherOperations?: IListFilterOperation[];
filter: ListFilterModel;
filterOptions: ListFilterOptions;
itemsSelected?: boolean;
}

Expand All @@ -58,9 +61,12 @@ export const ListFilter: React.FC<IListFilterProps> = (
}, 500);

const [editingCriterion, setEditingCriterion] = useState<
Criterion | undefined
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Criterion<any> | undefined
>(undefined);

const intl = useIntl();

useEffect(() => {
Mousetrap.bind("/", (e) => {
setQueryFocus();
Expand All @@ -69,17 +75,17 @@ export const ListFilter: React.FC<IListFilterProps> = (

Mousetrap.bind("r", () => onReshuffleRandomSort());
Mousetrap.bind("v g", () => {
if (props.filter.displayModeOptions.includes(DisplayMode.Grid)) {
if (props.filterOptions.displayModeOptions.includes(DisplayMode.Grid)) {
onChangeDisplayMode(DisplayMode.Grid);
}
});
Mousetrap.bind("v l", () => {
if (props.filter.displayModeOptions.includes(DisplayMode.List)) {
if (props.filterOptions.displayModeOptions.includes(DisplayMode.List)) {
onChangeDisplayMode(DisplayMode.List);
}
});
Mousetrap.bind("v w", () => {
if (props.filter.displayModeOptions.includes(DisplayMode.Wall)) {
if (props.filterOptions.displayModeOptions.includes(DisplayMode.Wall)) {
onChangeDisplayMode(DisplayMode.Wall);
}
});
Expand Down Expand Up @@ -160,9 +166,9 @@ export const ListFilter: React.FC<IListFilterProps> = (
props.onFilterUpdate(newFilter);
}

function onChangeSortBy(event: React.MouseEvent<HTMLAnchorElement>) {
function onChangeSortBy(eventKey: string | null) {
const newFilter = _.cloneDeep(props.filter);
newFilter.sortBy = event.currentTarget.text;
newFilter.sortBy = eventKey ?? undefined;
newFilter.currentPage = 1;
props.onFilterUpdate(newFilter);
}
Expand All @@ -180,7 +186,8 @@ export const ListFilter: React.FC<IListFilterProps> = (
props.onFilterUpdate(newFilter);
}

function onAddCriterion(criterion: Criterion, oldId?: string) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function onAddCriterion(criterion: Criterion<any>, oldId?: string) {
const newFilter = _.cloneDeep(props.filter);

// Find if we are editing an existing criteria, then modify that. Or create a new one.
Expand Down Expand Up @@ -208,7 +215,8 @@ export const ListFilter: React.FC<IListFilterProps> = (
setEditingCriterion(undefined);
}

function onRemoveCriterion(removedCriterion: Criterion) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function onRemoveCriterion(removedCriterion: Criterion<any>) {
const newFilter = _.cloneDeep(props.filter);
newFilter.criteria = newFilter.criteria.filter(
(criterion) => criterion.getId() !== removedCriterion.getId()
Expand All @@ -218,7 +226,8 @@ export const ListFilter: React.FC<IListFilterProps> = (
}

let removedCriterionId = "";
function onRemoveCriterionTag(criterion?: Criterion) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function onRemoveCriterionTag(criterion?: Criterion<any>) {
if (!criterion) {
return;
}
Expand All @@ -227,23 +236,33 @@ export const ListFilter: React.FC<IListFilterProps> = (
onRemoveCriterion(criterion);
}

function onClickCriterionTag(criterion?: Criterion) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function onClickCriterionTag(criterion?: Criterion<any>) {
if (!criterion || removedCriterionId !== "") {
return;
}
setEditingCriterion(criterion);
}

function renderSortByOptions() {
return props.filter.sortByOptions.map((option) => (
<Dropdown.Item
onClick={onChangeSortBy}
key={option}
className="bg-secondary text-white"
>
{option}
</Dropdown.Item>
));
return props.filterOptions.sortByOptions
.map((o) => {
return {
message: intl.formatMessage({ id: o.messageID }),
value: o.value,
};
})
.sort((a, b) => a.message.localeCompare(b.message))
.map((option) => (
<Dropdown.Item
onSelect={onChangeSortBy}
key={option.value}
className="bg-secondary text-white"
eventKey={option.value}
>
{option.message}
</Dropdown.Item>
));
}

function renderDisplayModeOptions() {
Expand Down Expand Up @@ -272,7 +291,7 @@ export const ListFilter: React.FC<IListFilterProps> = (
}
}

return props.filter.displayModeOptions.map((option) => (
return props.filterOptions.displayModeOptions.map((option) => (
<OverlayTrigger
key={option}
overlay={
Expand All @@ -298,7 +317,7 @@ export const ListFilter: React.FC<IListFilterProps> = (
key={criterion.getId()}
onClick={() => onClickCriterionTag(criterion)}
>
{criterion.getLabel()}
{criterion.getLabel(intl)}
<Button
variant="secondary"
onClick={() => onRemoveCriterionTag(criterion)}
Expand Down Expand Up @@ -450,6 +469,10 @@ export const ListFilter: React.FC<IListFilterProps> = (
}

function render() {
const currentSortBy = props.filterOptions.sortByOptions.find(
(o) => o.value === props.filter.sortBy
);

return (
<>
<ButtonToolbar className="align-items-center justify-content-center mb-2">
Expand All @@ -465,7 +488,7 @@ export const ListFilter: React.FC<IListFilterProps> = (

<InputGroup.Append>
<AddFilter
filter={props.filter}
filterOptions={props.filterOptions}
onAddCriterion={onAddCriterion}
onCancel={onCancelAddCriterion}
editingCriterion={editingCriterion}
Expand All @@ -475,7 +498,7 @@ export const ListFilter: React.FC<IListFilterProps> = (

<Dropdown as={ButtonGroup} className="mr-2">
<Dropdown.Toggle split variant="secondary" id="more-menu">
{props.filter.sortBy}
{intl.formatMessage({ id: currentSortBy?.messageID })}
</Dropdown.Toggle>
<Dropdown.Menu className="bg-secondary text-white">
{renderSortByOptions()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const MovieScenesPanel: React.FC<IMovieScenesPanel> = ({ movie }) => {
const movieValue = { id: movie.id!, label: movie.name! };
// if movie is already present, then we modify it, otherwise add
let movieCriterion = filter.criteria.find((c) => {
return c.type === "movies";
return c.criterionOption.value === "movies";
}) as MoviesCriterion;

if (
Expand Down
Loading