mirror of https://github.com/morpheus65535/bazarr
Fixed mass edit language clear not available
* Fixed mass edit language missing clear * Fixed mass edit profile clear * chore: Remove unused attributes
This commit is contained in:
parent
9787934820
commit
d7445bf39c
|
@ -9,7 +9,11 @@ import {
|
|||
useRefTracksByMovieId,
|
||||
useSubtitleAction,
|
||||
} from "@/apis/hooks";
|
||||
import { GroupedSelector, Selector } from "@/components/inputs";
|
||||
import {
|
||||
GroupedSelector,
|
||||
GroupedSelectorOptions,
|
||||
Selector,
|
||||
} from "@/components/inputs";
|
||||
import { useModals, withModal } from "@/modules/modals";
|
||||
import { task } from "@/modules/task";
|
||||
import { syncMaxOffsetSecondsOptions } from "@/pages/Settings/Subtitles/options";
|
||||
|
@ -17,11 +21,6 @@ import { toPython } from "@/utilities";
|
|||
|
||||
const TaskName = "Syncing Subtitle";
|
||||
|
||||
interface SelectOptions {
|
||||
group: string;
|
||||
items: { value: string; label: string }[];
|
||||
}
|
||||
|
||||
function useReferencedSubtitles(
|
||||
mediaType: "episode" | "movie",
|
||||
mediaId: number,
|
||||
|
@ -41,13 +40,13 @@ function useReferencedSubtitles(
|
|||
|
||||
const mediaData = mediaType === "episode" ? episodeData : movieData;
|
||||
|
||||
const subtitles: SelectOptions[] = [];
|
||||
const subtitles: GroupedSelectorOptions<string>[] = [];
|
||||
|
||||
if (!mediaData.data) {
|
||||
return [];
|
||||
} else {
|
||||
if (mediaData.data.audio_tracks.length > 0) {
|
||||
const embeddedAudioGroup: SelectOptions = {
|
||||
const embeddedAudioGroup: GroupedSelectorOptions<string> = {
|
||||
group: "Embedded audio tracks",
|
||||
items: [],
|
||||
};
|
||||
|
@ -63,7 +62,7 @@ function useReferencedSubtitles(
|
|||
}
|
||||
|
||||
if (mediaData.data.embedded_subtitles_tracks.length > 0) {
|
||||
const embeddedSubtitlesTrackGroup: SelectOptions = {
|
||||
const embeddedSubtitlesTrackGroup: GroupedSelectorOptions<string> = {
|
||||
group: "Embedded subtitles tracks",
|
||||
items: [],
|
||||
};
|
||||
|
@ -79,7 +78,7 @@ function useReferencedSubtitles(
|
|||
}
|
||||
|
||||
if (mediaData.data.external_subtitles_tracks.length > 0) {
|
||||
const externalSubtitlesFilesGroup: SelectOptions = {
|
||||
const externalSubtitlesFilesGroup: GroupedSelectorOptions<string> = {
|
||||
group: "External Subtitles files",
|
||||
items: [],
|
||||
};
|
||||
|
@ -127,11 +126,7 @@ const SyncSubtitleForm: FunctionComponent<Props> = ({
|
|||
const mediaId = selections[0].id;
|
||||
const subtitlesPath = selections[0].path;
|
||||
|
||||
const subtitles: SelectOptions[] = useReferencedSubtitles(
|
||||
mediaType,
|
||||
mediaId,
|
||||
subtitlesPath,
|
||||
);
|
||||
const subtitles = useReferencedSubtitles(mediaType, mediaId, subtitlesPath);
|
||||
|
||||
const form = useForm<FormValues>({
|
||||
initialValues: {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { useCallback, useMemo, useRef } from "react";
|
||||
import {
|
||||
ComboboxItem,
|
||||
ComboboxParsedItemGroup,
|
||||
ComboboxItemGroup,
|
||||
MultiSelect,
|
||||
MultiSelectProps,
|
||||
Select,
|
||||
SelectProps,
|
||||
} from "@mantine/core";
|
||||
import { isNull, isUndefined } from "lodash";
|
||||
import { isNull, isUndefined, noop } from "lodash";
|
||||
import { LOG } from "@/utilities/console";
|
||||
|
||||
export type SelectorOption<T> = Override<
|
||||
|
@ -35,9 +35,14 @@ function DefaultKeyBuilder<T>(value: T) {
|
|||
}
|
||||
}
|
||||
|
||||
export interface GroupedSelectorOptions<T> {
|
||||
group: string;
|
||||
items: SelectorOption<T>[];
|
||||
}
|
||||
|
||||
export type GroupedSelectorProps<T> = Override<
|
||||
{
|
||||
options: ComboboxParsedItemGroup[];
|
||||
options: ComboboxItemGroup[];
|
||||
getkey?: (value: T) => string;
|
||||
},
|
||||
Omit<SelectProps, "data">
|
||||
|
@ -47,6 +52,7 @@ export function GroupedSelector<T>({
|
|||
value,
|
||||
options,
|
||||
getkey = DefaultKeyBuilder,
|
||||
onOptionSubmit = noop,
|
||||
...select
|
||||
}: GroupedSelectorProps<T>) {
|
||||
return (
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
import { useCallback, useMemo, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Column, useRowSelect } from "react-table";
|
||||
import { Box, Container } from "@mantine/core";
|
||||
import { Box, Container, useCombobox } from "@mantine/core";
|
||||
import { faCheck, faUndo } from "@fortawesome/free-solid-svg-icons";
|
||||
import { UseMutationResult } from "@tanstack/react-query";
|
||||
import { uniqBy } from "lodash";
|
||||
import { useIsAnyMutationRunning, useLanguageProfiles } from "@/apis/hooks";
|
||||
import { SimpleTable, Toolbox } from "@/components";
|
||||
import { Selector, SelectorOption } from "@/components/inputs";
|
||||
import {
|
||||
GroupedSelector,
|
||||
GroupedSelectorOptions,
|
||||
SimpleTable,
|
||||
Toolbox,
|
||||
} from "@/components";
|
||||
import { useCustomSelection } from "@/components/tables/plugins";
|
||||
import { GetItemId, useSelectorOptions } from "@/utilities";
|
||||
|
||||
|
@ -36,10 +40,26 @@ function MassEditor<T extends Item.Base>(props: MassEditorProps<T>) {
|
|||
|
||||
const profileOptions = useSelectorOptions(profiles ?? [], (v) => v.name);
|
||||
|
||||
const profileOptionsWithAction = useMemo<SelectorOption<Language.Profile>[]>(
|
||||
() => [...profileOptions.options],
|
||||
[profileOptions.options],
|
||||
);
|
||||
const profileOptionsWithAction = useMemo<
|
||||
GroupedSelectorOptions<string>[]
|
||||
>(() => {
|
||||
return [
|
||||
{
|
||||
group: "Actions",
|
||||
items: [{ label: "Clear", value: "", profileId: null }],
|
||||
},
|
||||
{
|
||||
group: "Profiles",
|
||||
items: profileOptions.options.map((a) => {
|
||||
return {
|
||||
value: a.value.profileId.toString(),
|
||||
label: a.label,
|
||||
profileId: a.value.profileId,
|
||||
};
|
||||
}),
|
||||
},
|
||||
];
|
||||
}, [profileOptions.options]);
|
||||
|
||||
const getKey = useCallback((value: Language.Profile | null) => {
|
||||
if (value) {
|
||||
|
@ -94,8 +114,7 @@ function MassEditor<T extends Item.Base>(props: MassEditorProps<T>) {
|
|||
}, [dirties, mutateAsync]);
|
||||
|
||||
const setProfiles = useCallback(
|
||||
(profile: Language.Profile | null) => {
|
||||
const id = profile?.profileId ?? null;
|
||||
(id: number | null) => {
|
||||
const newItems = selections.map((v) => ({ ...v, profileId: id }));
|
||||
|
||||
setDirties((dirty) => {
|
||||
|
@ -105,18 +124,29 @@ function MassEditor<T extends Item.Base>(props: MassEditorProps<T>) {
|
|||
[selections],
|
||||
);
|
||||
|
||||
const combobox = useCombobox();
|
||||
|
||||
return (
|
||||
<Container fluid px={0}>
|
||||
<Toolbox>
|
||||
<Box>
|
||||
<Selector
|
||||
allowDeselect
|
||||
<GroupedSelector
|
||||
onClick={() => combobox.openDropdown()}
|
||||
onDropdownClose={() => {
|
||||
combobox.resetSelectedOption();
|
||||
}}
|
||||
placeholder="Change Profile"
|
||||
withCheckIcon={false}
|
||||
options={profileOptionsWithAction}
|
||||
getkey={getKey}
|
||||
disabled={selections.length === 0}
|
||||
onChange={setProfiles}
|
||||
></Selector>
|
||||
comboboxProps={{
|
||||
store: combobox,
|
||||
onOptionSubmit: (value) => {
|
||||
setProfiles(value ? +value : null);
|
||||
},
|
||||
}}
|
||||
></GroupedSelector>
|
||||
</Box>
|
||||
<Box>
|
||||
<Toolbox.Button icon={faUndo} onClick={onEnded}>
|
||||
|
|
Loading…
Reference in New Issue