From d7445bf39c2a6b4365064087c75c39972b22469d Mon Sep 17 00:00:00 2001 From: Anderson Shindy Oki Date: Wed, 12 Jun 2024 19:17:22 +0900 Subject: [PATCH] Fixed mass edit language clear not available * Fixed mass edit language missing clear * Fixed mass edit profile clear * chore: Remove unused attributes --- .../src/components/forms/SyncSubtitleForm.tsx | 25 ++++----- frontend/src/components/inputs/Selector.tsx | 12 +++- frontend/src/pages/views/MassEditor.tsx | 56 ++++++++++++++----- 3 files changed, 62 insertions(+), 31 deletions(-) diff --git a/frontend/src/components/forms/SyncSubtitleForm.tsx b/frontend/src/components/forms/SyncSubtitleForm.tsx index 867e49d72..f55b3ddb8 100644 --- a/frontend/src/components/forms/SyncSubtitleForm.tsx +++ b/frontend/src/components/forms/SyncSubtitleForm.tsx @@ -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[] = []; if (!mediaData.data) { return []; } else { if (mediaData.data.audio_tracks.length > 0) { - const embeddedAudioGroup: SelectOptions = { + const embeddedAudioGroup: GroupedSelectorOptions = { 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 = { 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 = { group: "External Subtitles files", items: [], }; @@ -127,11 +126,7 @@ const SyncSubtitleForm: FunctionComponent = ({ 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({ initialValues: { diff --git a/frontend/src/components/inputs/Selector.tsx b/frontend/src/components/inputs/Selector.tsx index ff06b3855..1825d314a 100644 --- a/frontend/src/components/inputs/Selector.tsx +++ b/frontend/src/components/inputs/Selector.tsx @@ -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 = Override< @@ -35,9 +35,14 @@ function DefaultKeyBuilder(value: T) { } } +export interface GroupedSelectorOptions { + group: string; + items: SelectorOption[]; +} + export type GroupedSelectorProps = Override< { - options: ComboboxParsedItemGroup[]; + options: ComboboxItemGroup[]; getkey?: (value: T) => string; }, Omit @@ -47,6 +52,7 @@ export function GroupedSelector({ value, options, getkey = DefaultKeyBuilder, + onOptionSubmit = noop, ...select }: GroupedSelectorProps) { return ( diff --git a/frontend/src/pages/views/MassEditor.tsx b/frontend/src/pages/views/MassEditor.tsx index 7476812e6..ee9ba476a 100644 --- a/frontend/src/pages/views/MassEditor.tsx +++ b/frontend/src/pages/views/MassEditor.tsx @@ -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(props: MassEditorProps) { const profileOptions = useSelectorOptions(profiles ?? [], (v) => v.name); - const profileOptionsWithAction = useMemo[]>( - () => [...profileOptions.options], - [profileOptions.options], - ); + const profileOptionsWithAction = useMemo< + GroupedSelectorOptions[] + >(() => { + 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(props: MassEditorProps) { }, [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(props: MassEditorProps) { [selections], ); + const combobox = useCombobox(); + return ( - combobox.openDropdown()} + onDropdownClose={() => { + combobox.resetSelectedOption(); + }} placeholder="Change Profile" + withCheckIcon={false} options={profileOptionsWithAction} getkey={getKey} disabled={selections.length === 0} - onChange={setProfiles} - > + comboboxProps={{ + store: combobox, + onOptionSubmit: (value) => { + setProfiles(value ? +value : null); + }, + }} + >