mirror of
https://github.com/fallenbagel/jellyseerr.git
synced 2026-01-01 04:08:45 -05:00
fix(ui): hide advanced request options when there is only one choice (#1591)
* refactor: remove unnecessary elements/indentation * fix(ui): hide advanced request options when there is only one choice
This commit is contained in:
@@ -26,7 +26,7 @@ type OptionType = {
|
|||||||
const Select = dynamic(() => import('react-select'), { ssr: false });
|
const Select = dynamic(() => import('react-select'), { ssr: false });
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
advancedoptions: 'Advanced Options',
|
advancedoptions: 'Advanced',
|
||||||
destinationserver: 'Destination Server',
|
destinationserver: 'Destination Server',
|
||||||
qualityprofile: 'Quality Profile',
|
qualityprofile: 'Quality Profile',
|
||||||
rootfolder: 'Root Folder',
|
rootfolder: 'Root Folder',
|
||||||
@@ -276,9 +276,9 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="p-4 bg-gray-600 rounded-md shadow">
|
<div className="p-4 bg-gray-600 rounded-md shadow">
|
||||||
{!!data && selectedServer !== null && (
|
{!!data && selectedServer !== null && (
|
||||||
<>
|
<div className="flex flex-col md:flex-row">
|
||||||
<div className="flex flex-col items-center justify-between md:flex-row">
|
{data.filter((server) => server.is4k === is4k).length > 1 && (
|
||||||
<div className="flex-grow flex-shrink-0 w-full mb-2 md:w-1/4 md:pr-4 md:mb-0">
|
<div className="flex-grow flex-shrink-0 w-full mb-3 md:w-1/4 md:pr-4 last:pr-0">
|
||||||
<label htmlFor="server">
|
<label htmlFor="server">
|
||||||
{intl.formatMessage(messages.destinationserver)}
|
{intl.formatMessage(messages.destinationserver)}
|
||||||
</label>
|
</label>
|
||||||
@@ -288,7 +288,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
value={selectedServer}
|
value={selectedServer}
|
||||||
onChange={(e) => setSelectedServer(Number(e.target.value))}
|
onChange={(e) => setSelectedServer(Number(e.target.value))}
|
||||||
onBlur={(e) => setSelectedServer(Number(e.target.value))}
|
onBlur={(e) => setSelectedServer(Number(e.target.value))}
|
||||||
className="block w-full py-2 pl-3 pr-10 mt-1 text-base leading-6 text-white transition duration-150 ease-in-out bg-gray-800 border-gray-700 rounded-md form-select focus:outline-none focus:ring-blue focus:border-blue-300 sm:text-sm sm:leading-5"
|
className="bg-gray-800 border-gray-700"
|
||||||
>
|
>
|
||||||
{data
|
{data
|
||||||
.filter((server) => server.is4k === is4k)
|
.filter((server) => server.is4k === is4k)
|
||||||
@@ -306,7 +306,11 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-grow flex-shrink-0 w-full mb-2 md:w-1/4 md:pr-4 md:mb-0">
|
)}
|
||||||
|
{(isValidating ||
|
||||||
|
!serverData ||
|
||||||
|
serverData.profiles.length > 1) && (
|
||||||
|
<div className="flex-grow flex-shrink-0 w-full mb-3 md:w-1/4 md:pr-4 last:pr-0">
|
||||||
<label htmlFor="profile">
|
<label htmlFor="profile">
|
||||||
{intl.formatMessage(messages.qualityprofile)}
|
{intl.formatMessage(messages.qualityprofile)}
|
||||||
</label>
|
</label>
|
||||||
@@ -316,7 +320,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
value={selectedProfile}
|
value={selectedProfile}
|
||||||
onChange={(e) => setSelectedProfile(Number(e.target.value))}
|
onChange={(e) => setSelectedProfile(Number(e.target.value))}
|
||||||
onBlur={(e) => setSelectedProfile(Number(e.target.value))}
|
onBlur={(e) => setSelectedProfile(Number(e.target.value))}
|
||||||
className="block w-full py-2 pl-3 pr-10 mt-1 text-base leading-6 text-white transition duration-150 ease-in-out bg-gray-800 border-gray-700 rounded-md form-select focus:outline-none focus:ring-blue focus:border-blue-300 sm:text-sm sm:leading-5"
|
className="bg-gray-800 border-gray-700"
|
||||||
disabled={isValidating || !serverData}
|
disabled={isValidating || !serverData}
|
||||||
>
|
>
|
||||||
{(isValidating || !serverData) && (
|
{(isValidating || !serverData) && (
|
||||||
@@ -346,11 +350,11 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div
|
)}
|
||||||
className={`flex-grow flex-shrink-0 w-full mb-2 md:w-1/4 md:mb-0 ${
|
{(isValidating ||
|
||||||
type === 'tv' ? 'md:pr-4' : ''
|
!serverData ||
|
||||||
}`}
|
serverData.rootFolders.length > 1) && (
|
||||||
>
|
<div className="flex-grow flex-shrink-0 w-full mb-3 md:w-1/4 md:pr-4 last:pr-0">
|
||||||
<label htmlFor="folder">
|
<label htmlFor="folder">
|
||||||
{intl.formatMessage(messages.rootfolder)}
|
{intl.formatMessage(messages.rootfolder)}
|
||||||
</label>
|
</label>
|
||||||
@@ -360,7 +364,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
value={selectedFolder}
|
value={selectedFolder}
|
||||||
onChange={(e) => setSelectedFolder(e.target.value)}
|
onChange={(e) => setSelectedFolder(e.target.value)}
|
||||||
onBlur={(e) => setSelectedFolder(e.target.value)}
|
onBlur={(e) => setSelectedFolder(e.target.value)}
|
||||||
className="block w-full py-2 pl-3 pr-10 mt-1 text-base leading-6 text-white transition duration-150 ease-in-out bg-gray-800 border-gray-700 rounded-md form-select focus:outline-none focus:ring-blue focus:border-blue-300 sm:text-sm sm:leading-5"
|
className="bg-gray-800 border-gray-700"
|
||||||
disabled={isValidating || !serverData}
|
disabled={isValidating || !serverData}
|
||||||
>
|
>
|
||||||
{(isValidating || !serverData) && (
|
{(isValidating || !serverData) && (
|
||||||
@@ -399,8 +403,12 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
{type === 'tv' && (
|
)}
|
||||||
<div className="flex-grow flex-shrink-0 w-full mb-2 md:w-1/4 md:mb-0">
|
{type === 'tv' &&
|
||||||
|
(isValidating ||
|
||||||
|
!serverData ||
|
||||||
|
(serverData.languageProfiles ?? []).length > 1) && (
|
||||||
|
<div className="flex-grow flex-shrink-0 w-full mb-3 md:w-1/4 md:pr-4 last:pr-0">
|
||||||
<label htmlFor="language">
|
<label htmlFor="language">
|
||||||
{intl.formatMessage(messages.languageprofile)}
|
{intl.formatMessage(messages.languageprofile)}
|
||||||
</label>
|
</label>
|
||||||
@@ -414,7 +422,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
onBlur={(e) =>
|
onBlur={(e) =>
|
||||||
setSelectedLanguage(parseInt(e.target.value))
|
setSelectedLanguage(parseInt(e.target.value))
|
||||||
}
|
}
|
||||||
className="block w-full py-2 pl-3 pr-10 mt-1 text-base leading-6 text-white transition duration-150 ease-in-out bg-gray-800 border-gray-700 rounded-md form-select focus:outline-none focus:ring-blue focus:border-blue-300 sm:text-sm sm:leading-5"
|
className="bg-gray-800 border-gray-700"
|
||||||
disabled={isValidating || !serverData}
|
disabled={isValidating || !serverData}
|
||||||
>
|
>
|
||||||
{(isValidating || !serverData) && (
|
{(isValidating || !serverData) && (
|
||||||
@@ -447,147 +455,145 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{!!data && selectedServer !== null && (
|
|
||||||
<div className="mt-0 sm:mt-2">
|
|
||||||
<label htmlFor="tags">{intl.formatMessage(messages.tags)}</label>
|
|
||||||
<Select
|
|
||||||
name="tags"
|
|
||||||
options={(serverData?.tags ?? []).map((tag) => ({
|
|
||||||
label: tag.label,
|
|
||||||
value: tag.id,
|
|
||||||
}))}
|
|
||||||
isMulti
|
|
||||||
isDisabled={isValidating || !serverData}
|
|
||||||
placeholder={
|
|
||||||
isValidating || !serverData
|
|
||||||
? intl.formatMessage(globalMessages.loading)
|
|
||||||
: intl.formatMessage(messages.selecttags)
|
|
||||||
}
|
|
||||||
className="react-select-container react-select-container-dark"
|
|
||||||
classNamePrefix="react-select"
|
|
||||||
value={selectedTags.map((tagId) => {
|
|
||||||
const foundTag = serverData?.tags.find(
|
|
||||||
(tag) => tag.id === tagId
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
value: foundTag?.id,
|
|
||||||
label: foundTag?.label,
|
|
||||||
};
|
|
||||||
})}
|
|
||||||
onChange={(
|
|
||||||
value: OptionTypeBase | OptionsType<OptionType> | null
|
|
||||||
) => {
|
|
||||||
if (!Array.isArray(value)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setSelectedTags(value?.map((option) => option.value));
|
|
||||||
}}
|
|
||||||
noOptionsMessage={() => intl.formatMessage(messages.notagoptions)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{selectedServer !== null &&
|
||||||
|
(isValidating || !serverData || !!serverData?.tags?.length) && (
|
||||||
|
<div className="mb-2">
|
||||||
|
<label htmlFor="tags">{intl.formatMessage(messages.tags)}</label>
|
||||||
|
<Select
|
||||||
|
name="tags"
|
||||||
|
options={(serverData?.tags ?? []).map((tag) => ({
|
||||||
|
label: tag.label,
|
||||||
|
value: tag.id,
|
||||||
|
}))}
|
||||||
|
isMulti
|
||||||
|
isDisabled={isValidating || !serverData}
|
||||||
|
placeholder={
|
||||||
|
isValidating || !serverData
|
||||||
|
? intl.formatMessage(globalMessages.loading)
|
||||||
|
: intl.formatMessage(messages.selecttags)
|
||||||
|
}
|
||||||
|
className="react-select-container react-select-container-dark"
|
||||||
|
classNamePrefix="react-select"
|
||||||
|
value={selectedTags.map((tagId) => {
|
||||||
|
const foundTag = serverData?.tags.find(
|
||||||
|
(tag) => tag.id === tagId
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
value: foundTag?.id,
|
||||||
|
label: foundTag?.label,
|
||||||
|
};
|
||||||
|
})}
|
||||||
|
onChange={(
|
||||||
|
value: OptionTypeBase | OptionsType<OptionType> | null
|
||||||
|
) => {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setSelectedTags(value?.map((option) => option.value));
|
||||||
|
}}
|
||||||
|
noOptionsMessage={() =>
|
||||||
|
intl.formatMessage(messages.notagoptions)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{hasPermission([Permission.MANAGE_REQUESTS, Permission.MANAGE_USERS]) &&
|
{hasPermission([Permission.MANAGE_REQUESTS, Permission.MANAGE_USERS]) &&
|
||||||
selectedUser && (
|
selectedUser && (
|
||||||
<div className="mt-2 first:mt-0">
|
<Listbox
|
||||||
<Listbox
|
as="div"
|
||||||
as="div"
|
value={selectedUser}
|
||||||
value={selectedUser}
|
onChange={(value) => setSelectedUser(value)}
|
||||||
onChange={(value) => setSelectedUser(value)}
|
className="space-y-1"
|
||||||
className="space-y-1"
|
>
|
||||||
>
|
{({ open }) => (
|
||||||
{({ open }) => (
|
<>
|
||||||
<>
|
<Listbox.Label>
|
||||||
<Listbox.Label>
|
{intl.formatMessage(messages.requestas)}
|
||||||
{intl.formatMessage(messages.requestas)}
|
</Listbox.Label>
|
||||||
</Listbox.Label>
|
<div className="relative">
|
||||||
<div className="relative">
|
<span className="inline-block w-full rounded-md shadow-sm">
|
||||||
<span className="inline-block w-full rounded-md shadow-sm">
|
<Listbox.Button className="relative w-full py-2 pl-3 pr-10 text-left text-white transition duration-150 ease-in-out bg-gray-800 border border-gray-700 rounded-md cursor-default focus:outline-none focus:shadow-outline-blue focus:border-blue-300 sm:text-sm sm:leading-5">
|
||||||
<Listbox.Button className="relative w-full py-2 pl-3 pr-10 text-left text-white transition duration-150 ease-in-out bg-gray-800 border border-gray-700 rounded-md cursor-default focus:outline-none focus:shadow-outline-blue focus:border-blue-300 sm:text-sm sm:leading-5">
|
<span className="flex items-center">
|
||||||
<span className="flex items-center">
|
<img
|
||||||
<img
|
src={selectedUser.avatar}
|
||||||
src={selectedUser.avatar}
|
alt=""
|
||||||
alt=""
|
className="flex-shrink-0 w-6 h-6 rounded-full"
|
||||||
className="flex-shrink-0 w-6 h-6 rounded-full"
|
/>
|
||||||
/>
|
<span className="block ml-3">
|
||||||
<span className="block ml-3">
|
{selectedUser.displayName}
|
||||||
{selectedUser.displayName}
|
|
||||||
</span>
|
|
||||||
<span className="ml-1 text-gray-400 truncate">
|
|
||||||
({selectedUser.email})
|
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
<span className="absolute inset-y-0 right-0 flex items-center pr-2 text-gray-500 pointer-events-none">
|
<span className="ml-1 text-gray-400 truncate">
|
||||||
<ChevronDownIcon className="w-5 h-5" />
|
({selectedUser.email})
|
||||||
</span>
|
</span>
|
||||||
</Listbox.Button>
|
</span>
|
||||||
</span>
|
<span className="absolute inset-y-0 right-0 flex items-center pr-2 text-gray-500 pointer-events-none">
|
||||||
|
<ChevronDownIcon className="w-5 h-5" />
|
||||||
|
</span>
|
||||||
|
</Listbox.Button>
|
||||||
|
</span>
|
||||||
|
|
||||||
<Transition
|
<Transition
|
||||||
show={open}
|
show={open}
|
||||||
enter="transition ease-in duration-300"
|
enter="transition ease-in duration-300"
|
||||||
enterFrom="opacity-0"
|
enterFrom="opacity-0"
|
||||||
enterTo="opacity-100"
|
enterTo="opacity-100"
|
||||||
leave="transition ease-in duration-100"
|
leave="transition ease-in duration-100"
|
||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
className="w-full mt-1 bg-gray-800 rounded-md shadow-lg"
|
className="w-full mt-1 bg-gray-800 rounded-md shadow-lg"
|
||||||
|
>
|
||||||
|
<Listbox.Options
|
||||||
|
static
|
||||||
|
className="py-1 overflow-auto text-base leading-6 rounded-md shadow-xs max-h-60 focus:outline-none sm:text-sm sm:leading-5"
|
||||||
>
|
>
|
||||||
<Listbox.Options
|
{userData?.results.map((user) => (
|
||||||
static
|
<Listbox.Option key={user.id} value={user}>
|
||||||
className="py-1 overflow-auto text-base leading-6 rounded-md shadow-xs max-h-60 focus:outline-none sm:text-sm sm:leading-5"
|
{({ selected, active }) => (
|
||||||
>
|
<div
|
||||||
{userData?.results.map((user) => (
|
className={`${
|
||||||
<Listbox.Option key={user.id} value={user}>
|
active
|
||||||
{({ selected, active }) => (
|
? 'text-white bg-indigo-600'
|
||||||
<div
|
: 'text-gray-300'
|
||||||
|
} cursor-default select-none relative py-2 pl-8 pr-4`}
|
||||||
|
>
|
||||||
|
<span
|
||||||
className={`${
|
className={`${
|
||||||
active
|
selected ? 'font-semibold' : 'font-normal'
|
||||||
? 'text-white bg-indigo-600'
|
} flex items-center`}
|
||||||
: 'text-gray-300'
|
|
||||||
} cursor-default select-none relative py-2 pl-8 pr-4`}
|
|
||||||
>
|
>
|
||||||
|
<img
|
||||||
|
src={user.avatar}
|
||||||
|
alt=""
|
||||||
|
className="flex-shrink-0 w-6 h-6 rounded-full"
|
||||||
|
/>
|
||||||
|
<span className="flex-shrink-0 block ml-3">
|
||||||
|
{user.displayName}
|
||||||
|
</span>
|
||||||
|
<span className="ml-1 text-gray-400 truncate">
|
||||||
|
({user.email})
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
{selected && (
|
||||||
<span
|
<span
|
||||||
className={`${
|
className={`${
|
||||||
selected ? 'font-semibold' : 'font-normal'
|
active ? 'text-white' : 'text-indigo-600'
|
||||||
} flex items-center`}
|
} absolute inset-y-0 left-0 flex items-center pl-1.5`}
|
||||||
>
|
>
|
||||||
<img
|
<CheckIcon className="w-5 h-5" />
|
||||||
src={user.avatar}
|
|
||||||
alt=""
|
|
||||||
className="flex-shrink-0 w-6 h-6 rounded-full"
|
|
||||||
/>
|
|
||||||
<span className="flex-shrink-0 block ml-3">
|
|
||||||
{user.displayName}
|
|
||||||
</span>
|
|
||||||
<span className="ml-1 text-gray-400 truncate">
|
|
||||||
({user.email})
|
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
{selected && (
|
)}
|
||||||
<span
|
</div>
|
||||||
className={`${
|
)}
|
||||||
active
|
</Listbox.Option>
|
||||||
? 'text-white'
|
))}
|
||||||
: 'text-indigo-600'
|
</Listbox.Options>
|
||||||
} absolute inset-y-0 left-0 flex items-center pl-1.5`}
|
</Transition>
|
||||||
>
|
</div>
|
||||||
<CheckIcon className="w-5 h-5" />
|
</>
|
||||||
</span>
|
)}
|
||||||
)}
|
</Listbox>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Listbox.Option>
|
|
||||||
))}
|
|
||||||
</Listbox.Options>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Listbox>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
{isAnime && (
|
{isAnime && (
|
||||||
<div className="mt-4 italic">
|
<div className="mt-4 italic">
|
||||||
|
|||||||
@@ -183,7 +183,7 @@
|
|||||||
"components.RequestList.showallrequests": "Show All Requests",
|
"components.RequestList.showallrequests": "Show All Requests",
|
||||||
"components.RequestList.sortAdded": "Request Date",
|
"components.RequestList.sortAdded": "Request Date",
|
||||||
"components.RequestList.sortModified": "Last Modified",
|
"components.RequestList.sortModified": "Last Modified",
|
||||||
"components.RequestModal.AdvancedRequester.advancedoptions": "Advanced Options",
|
"components.RequestModal.AdvancedRequester.advancedoptions": "Advanced",
|
||||||
"components.RequestModal.AdvancedRequester.animenote": "* This series is an anime.",
|
"components.RequestModal.AdvancedRequester.animenote": "* This series is an anime.",
|
||||||
"components.RequestModal.AdvancedRequester.default": "{name} (Default)",
|
"components.RequestModal.AdvancedRequester.default": "{name} (Default)",
|
||||||
"components.RequestModal.AdvancedRequester.destinationserver": "Destination Server",
|
"components.RequestModal.AdvancedRequester.destinationserver": "Destination Server",
|
||||||
|
|||||||
Reference in New Issue
Block a user