fix(ui): Notification-related string/UI edits and field validation (#985)

pull/823/head
TheCatLady 3 years ago committed by GitHub
parent 8589eabfff
commit c88fcb2e2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,15 +5,17 @@ import NotificationType from './NotificationType';
const messages = defineMessages({ const messages = defineMessages({
mediarequested: 'Media Requested', mediarequested: 'Media Requested',
mediarequestedDescription: mediarequestedDescription:
'Sends a notification when new media is requested. For certain agents, this will only send the notification to admins or users with the "Manage Requests" permission.', 'Sends a notification when media is requested and requires approval.',
mediaapproved: 'Media Approved', mediaapproved: 'Media Approved',
mediaapprovedDescription: 'Sends a notification when media is approved.', mediaapprovedDescription:
'Sends a notification when media is approved.\
By default, automatically approved requests will not trigger notifications.',
mediaavailable: 'Media Available', mediaavailable: 'Media Available',
mediaavailableDescription: mediaavailableDescription:
'Sends a notification when media becomes available.', 'Sends a notification when media becomes available.',
mediafailed: 'Media Failed', mediafailed: 'Media Failed',
mediafailedDescription: mediafailedDescription:
'Sends a notification when media fails to be added to services (Radarr/Sonarr). For certain agents, this will only send the notification to admins or users with the "Manage Requests" permission.', 'Sends a notification when media fails to be added to Radarr or Sonarr.',
mediadeclined: 'Media Declined', mediadeclined: 'Media Declined',
mediadeclinedDescription: 'Sends a notification when a request is declined.', mediadeclinedDescription: 'Sends a notification when a request is declined.',
}); });

@ -6,7 +6,7 @@ import { useIntl, defineMessages } from 'react-intl';
export const messages = defineMessages({ export const messages = defineMessages({
admin: 'Admin', admin: 'Admin',
adminDescription: adminDescription:
'Full administrator access. Bypasses all permission checks.', 'Full administrator access. Bypasses all other permission checks.',
users: 'Manage Users', users: 'Manage Users',
usersDescription: usersDescription:
'Grants permission to manage Overseerr users. Users with this permission cannot modify users with or grant the Admin privilege.', 'Grants permission to manage Overseerr users. Users with this permission cannot modify users with or grant the Admin privilege.',

@ -15,7 +15,7 @@ const messages = defineMessages({
agentenabled: 'Enable Agent', agentenabled: 'Enable Agent',
webhookUrl: 'Webhook URL', webhookUrl: 'Webhook URL',
webhookUrlPlaceholder: 'Server Settings → Integrations → Webhooks', webhookUrlPlaceholder: 'Server Settings → Integrations → Webhooks',
discordsettingssaved: 'Discord notification settings saved!', discordsettingssaved: 'Discord notification settings saved successfully!',
discordsettingsfailed: 'Discord notification settings failed to save.', discordsettingsfailed: 'Discord notification settings failed to save.',
testsent: 'Test notification sent!', testsent: 'Test notification sent!',
test: 'Test', test: 'Test',

@ -8,6 +8,7 @@ import axios from 'axios';
import * as Yup from 'yup'; import * as Yup from 'yup';
import { useToasts } from 'react-toast-notifications'; import { useToasts } from 'react-toast-notifications';
import NotificationTypeSelector from '../../NotificationTypeSelector'; import NotificationTypeSelector from '../../NotificationTypeSelector';
import Alert from '../../Common/Alert';
const messages = defineMessages({ const messages = defineMessages({
save: 'Save Changes', save: 'Save Changes',
@ -21,7 +22,7 @@ const messages = defineMessages({
enableSsl: 'Enable SSL', enableSsl: 'Enable SSL',
authUser: 'SMTP Username', authUser: 'SMTP Username',
authPass: 'SMTP Password', authPass: 'SMTP Password',
emailsettingssaved: 'Email notification settings saved!', emailsettingssaved: 'Email notification settings saved successfully!',
emailsettingsfailed: 'Email notification settings failed to save.', emailsettingsfailed: 'Email notification settings failed to save.',
test: 'Test', test: 'Test',
testsent: 'Test notification sent!', testsent: 'Test notification sent!',
@ -31,6 +32,10 @@ const messages = defineMessages({
senderName: 'Sender Name', senderName: 'Sender Name',
notificationtypes: 'Notification Types', notificationtypes: 'Notification Types',
validationEmail: 'You must provide a valid email address', validationEmail: 'You must provide a valid email address',
emailNotificationTypesAlert: 'Notification Email Recipients',
emailNotificationTypesAlertDescription:
'For the "Media Requested" and "Media Failed" notification types,\
notifications will only be sent to users with the "Manage Requests" permission.',
}); });
const NotificationsEmail: React.FC = () => { const NotificationsEmail: React.FC = () => {
@ -124,180 +129,193 @@ const NotificationsEmail: React.FC = () => {
}; };
return ( return (
<Form className="section"> <>
<div className="form-row"> <Alert
<label htmlFor="enabled" className="checkbox-label"> title={intl.formatMessage(messages.emailNotificationTypesAlert)}
{intl.formatMessage(messages.agentenabled)} type="info"
</label> >
<div className="form-input"> {intl.formatMessage(
<Field type="checkbox" id="enabled" name="enabled" /> messages.emailNotificationTypesAlertDescription
</div> )}
</div> </Alert>
<div className="form-row"> <Form className="section">
<label htmlFor="emailFrom" className="text-label"> <div className="form-row">
{intl.formatMessage(messages.emailsender)} <label htmlFor="enabled" className="checkbox-label">
</label> {intl.formatMessage(messages.agentenabled)}
<div className="form-input"> </label>
<div className="flex max-w-lg rounded-md shadow-sm"> <div className="form-input">
<Field <Field type="checkbox" id="enabled" name="enabled" />
id="emailFrom"
name="emailFrom"
type="text"
placeholder="no-reply@example.com"
/>
</div> </div>
{errors.emailFrom && touched.emailFrom && (
<div className="error">{errors.emailFrom}</div>
)}
</div> </div>
</div> <div className="form-row">
<div className="form-row"> <label htmlFor="emailFrom" className="text-label">
<label htmlFor="senderName" className="text-label"> {intl.formatMessage(messages.emailsender)}
{intl.formatMessage(messages.senderName)} </label>
</label> <div className="form-input">
<div className="form-input"> <div className="flex max-w-lg rounded-md shadow-sm">
<div className="flex max-w-lg rounded-md shadow-sm"> <Field
<Field id="emailFrom"
id="senderName" name="emailFrom"
name="senderName" type="text"
placeholder="Overseerr" placeholder="no-reply@example.com"
type="text" />
/> </div>
{errors.emailFrom && touched.emailFrom && (
<div className="error">{errors.emailFrom}</div>
)}
</div> </div>
</div> </div>
</div> <div className="form-row">
<div className="form-row"> <label htmlFor="senderName" className="text-label">
<label htmlFor="smtpHost" className="text-label"> {intl.formatMessage(messages.senderName)}
{intl.formatMessage(messages.smtpHost)} </label>
</label> <div className="form-input">
<div className="form-input"> <div className="flex max-w-lg rounded-md shadow-sm">
<div className="flex max-w-lg rounded-md shadow-sm"> <Field
<Field id="senderName"
id="smtpHost" name="senderName"
name="smtpHost" placeholder="Overseerr"
type="text" type="text"
placeholder="localhost" />
/> </div>
</div> </div>
{errors.smtpHost && touched.smtpHost && (
<div className="error">{errors.smtpHost}</div>
)}
</div> </div>
</div> <div className="form-row">
<div className="form-row"> <label htmlFor="smtpHost" className="text-label">
<label htmlFor="smtpPort" className="text-label"> {intl.formatMessage(messages.smtpHost)}
{intl.formatMessage(messages.smtpPort)} </label>
</label> <div className="form-input">
<div className="form-input"> <div className="flex max-w-lg rounded-md shadow-sm">
<div className="flex max-w-lg rounded-md shadow-sm"> <Field
<Field id="smtpHost"
id="smtpPort" name="smtpHost"
name="smtpPort" type="text"
type="text" placeholder="localhost"
placeholder="465" />
/> </div>
{errors.smtpHost && touched.smtpHost && (
<div className="error">{errors.smtpHost}</div>
)}
</div> </div>
{errors.smtpPort && touched.smtpPort && (
<div className="error">{errors.smtpPort}</div>
)}
</div>
</div>
<div className="form-row">
<label htmlFor="secure" className="checkbox-label">
<span>{intl.formatMessage(messages.enableSsl)}</span>
<span className="label-tip">
{intl.formatMessage(messages.ssldisabletip)}
</span>
</label>
<div className="form-input">
<Field type="checkbox" id="secure" name="secure" />
</div> </div>
</div> <div className="form-row">
<div className="form-row"> <label htmlFor="smtpPort" className="text-label">
<label htmlFor="allowSelfSigned" className="checkbox-label"> {intl.formatMessage(messages.smtpPort)}
{intl.formatMessage(messages.allowselfsigned)} </label>
</label> <div className="form-input">
<div className="form-input"> <div className="flex max-w-lg rounded-md shadow-sm sm:max-w-xs">
<Field <Field
type="checkbox" id="smtpPort"
id="allowSelfSigned" name="smtpPort"
name="allowSelfSigned" type="text"
/> placeholder="465"
className="short"
/>
</div>
{errors.smtpPort && touched.smtpPort && (
<div className="error">{errors.smtpPort}</div>
)}
</div>
</div> </div>
</div> <div className="form-row">
<div className="form-row"> <label htmlFor="secure" className="checkbox-label">
<label htmlFor="authUser" className="text-label"> <span>{intl.formatMessage(messages.enableSsl)}</span>
{intl.formatMessage(messages.authUser)} <span className="label-tip">
</label> {intl.formatMessage(messages.ssldisabletip)}
<div className="form-input"> </span>
<div className="flex max-w-lg rounded-md shadow-sm"> </label>
<Field id="authUser" name="authUser" type="text" /> <div className="form-input">
<Field type="checkbox" id="secure" name="secure" />
</div> </div>
</div> </div>
</div> <div className="form-row">
<div className="form-row"> <label htmlFor="allowSelfSigned" className="checkbox-label">
<label htmlFor="authPass" className="text-label"> {intl.formatMessage(messages.allowselfsigned)}
{intl.formatMessage(messages.authPass)} </label>
</label> <div className="form-input">
<div className="form-input">
<div className="flex max-w-lg rounded-md shadow-sm">
<Field <Field
id="authPass" type="checkbox"
name="authPass" id="allowSelfSigned"
type="password" name="allowSelfSigned"
autoComplete="off"
/> />
</div> </div>
</div> </div>
</div>
<div
role="group"
aria-labelledby="group-label"
className="form-group"
>
<div className="form-row"> <div className="form-row">
<span id="group-label" className="group-label"> <label htmlFor="authUser" className="text-label">
{intl.formatMessage(messages.notificationtypes)} {intl.formatMessage(messages.authUser)}
</span> </label>
<div className="form-input"> <div className="form-input">
<div className="max-w-lg"> <div className="flex max-w-lg rounded-md shadow-sm">
<NotificationTypeSelector <Field id="authUser" name="authUser" type="text" />
currentTypes={values.types} </div>
onUpdate={(newTypes) => setFieldValue('types', newTypes)} </div>
</div>
<div className="form-row">
<label htmlFor="authPass" className="text-label">
{intl.formatMessage(messages.authPass)}
</label>
<div className="form-input">
<div className="flex max-w-lg rounded-md shadow-sm">
<Field
id="authPass"
name="authPass"
type="password"
autoComplete="off"
/> />
</div> </div>
</div> </div>
</div> </div>
</div> <div
<div className="actions"> role="group"
<div className="flex justify-end"> aria-labelledby="group-label"
<span className="inline-flex ml-3 rounded-md shadow-sm"> className="form-group"
<Button >
buttonType="warning" <div className="form-row">
disabled={isSubmitting || !isValid} <span id="group-label" className="group-label">
onClick={(e) => { {intl.formatMessage(messages.notificationtypes)}
e.preventDefault(); </span>
<div className="form-input">
<div className="max-w-lg">
<NotificationTypeSelector
currentTypes={values.types}
onUpdate={(newTypes) =>
setFieldValue('types', newTypes)
}
/>
</div>
</div>
</div>
</div>
<div className="actions">
<div className="flex justify-end">
<span className="inline-flex ml-3 rounded-md shadow-sm">
<Button
buttonType="warning"
disabled={isSubmitting || !isValid}
onClick={(e) => {
e.preventDefault();
testSettings(); testSettings();
}} }}
> >
{intl.formatMessage(messages.test)} {intl.formatMessage(messages.test)}
</Button> </Button>
</span> </span>
<span className="inline-flex ml-3 rounded-md shadow-sm"> <span className="inline-flex ml-3 rounded-md shadow-sm">
<Button <Button
buttonType="primary" buttonType="primary"
type="submit" type="submit"
disabled={isSubmitting || !isValid} disabled={isSubmitting || !isValid}
> >
{isSubmitting {isSubmitting
? intl.formatMessage(messages.saving) ? intl.formatMessage(messages.saving)
: intl.formatMessage(messages.save)} : intl.formatMessage(messages.save)}
</Button> </Button>
</span> </span>
</div>
</div> </div>
</div> </Form>
</Form> </>
); );
}} }}
</Formik> </Formik>

@ -15,14 +15,15 @@ const messages = defineMessages({
saving: 'Saving…', saving: 'Saving…',
agentEnabled: 'Enable Agent', agentEnabled: 'Enable Agent',
accessToken: 'Access Token', accessToken: 'Access Token',
validationAccessTokenRequired: 'You must provide an access token.', validationAccessTokenRequired: 'You must provide an access token',
pushbulletSettingsSaved: 'Pushbullet notification settings saved!', pushbulletSettingsSaved:
'Pushbullet notification settings saved successfully!',
pushbulletSettingsFailed: 'Pushbullet notification settings failed to save.', pushbulletSettingsFailed: 'Pushbullet notification settings failed to save.',
testSent: 'Test notification sent!', testSent: 'Test notification sent!',
test: 'Test', test: 'Test',
settingUpPushbullet: 'Setting Up Pushbullet Notifications', settingUpPushbullet: 'Setting Up Pushbullet Notifications',
settingUpPushbulletDescription: settingUpPushbulletDescription:
'To configure Pushbullet notifications, you need to <CreateAccessTokenLink>create an access token</CreateAccessTokenLink> and enter it below.', 'To configure Pushbullet notifications, you will need to <CreateAccessTokenLink>create an access token</CreateAccessTokenLink> and enter it below.',
notificationTypes: 'Notification Types', notificationTypes: 'Notification Types',
}); });

@ -14,19 +14,19 @@ const messages = defineMessages({
save: 'Save Changes', save: 'Save Changes',
saving: 'Saving…', saving: 'Saving…',
agentenabled: 'Enable Agent', agentenabled: 'Enable Agent',
accessToken: 'Access Token', accessToken: 'Application/API Token',
userToken: 'User Token', userToken: 'User Key',
validationAccessTokenRequired: 'You must provide an access token.', validationAccessTokenRequired: 'You must provide a valid application token',
validationUserTokenRequired: 'You must provide a user token.', validationUserTokenRequired: 'You must provide a valid user key',
pushoversettingssaved: 'Pushover notification settings saved!', pushoversettingssaved: 'Pushover notification settings saved successfully!',
pushoversettingsfailed: 'Pushover notification settings failed to save.', pushoversettingsfailed: 'Pushover notification settings failed to save.',
testsent: 'Test notification sent!', testsent: 'Test notification sent!',
test: 'Test', test: 'Test',
settinguppushover: 'Setting Up Pushover Notifications', settinguppushover: 'Setting Up Pushover Notifications',
settinguppushoverDescription: settinguppushoverDescription:
'To configure Pushover notifications, you need to <RegisterApplicationLink>register an application</RegisterApplicationLink> and get the access token.\ 'To configure Pushover notifications, you will need to <RegisterApplicationLink>register an application</RegisterApplicationLink> and enter the API key below.\
When setting up the application, you can use one of the icons in the <IconLink>public folder</IconLink> on GitHub.\ (You can use one of our <IconLink>official icons on GitHub</IconLink>.)\
You also need the Pushover user token, which can be found on the start page when you log in.', You will need also need your user key.',
notificationtypes: 'Notification Types', notificationtypes: 'Notification Types',
}); });
@ -38,12 +38,18 @@ const NotificationsPushover: React.FC = () => {
); );
const NotificationsPushoverSchema = Yup.object().shape({ const NotificationsPushoverSchema = Yup.object().shape({
accessToken: Yup.string().required( accessToken: Yup.string()
intl.formatMessage(messages.validationAccessTokenRequired) .required(intl.formatMessage(messages.validationAccessTokenRequired))
), .matches(
userToken: Yup.string().required( /^a[A-Za-z0-9]{29}$/,
intl.formatMessage(messages.validationUserTokenRequired) intl.formatMessage(messages.validationAccessTokenRequired)
), ),
userToken: Yup.string()
.required(intl.formatMessage(messages.validationUserTokenRequired))
.matches(
/^[ug][A-Za-z0-9]{29}$/,
intl.formatMessage(messages.validationUserTokenRequired)
),
}); });
if (!data && !error) { if (!data && !error) {

@ -15,8 +15,7 @@ const messages = defineMessages({
saving: 'Saving…', saving: 'Saving…',
agentenabled: 'Enable Agent', agentenabled: 'Enable Agent',
webhookUrl: 'Webhook URL', webhookUrl: 'Webhook URL',
webhookUrlPlaceholder: 'Webhook URL', slacksettingssaved: 'Slack notification settings saved successfully!',
slacksettingssaved: 'Slack notification settings saved!',
slacksettingsfailed: 'Slack notification settings failed to save.', slacksettingsfailed: 'Slack notification settings failed to save.',
testsent: 'Test notification sent!', testsent: 'Test notification sent!',
test: 'Test', test: 'Test',
@ -131,14 +130,7 @@ const NotificationsSlack: React.FC = () => {
</label> </label>
<div className="form-input"> <div className="form-input">
<div className="flex max-w-lg rounded-md shadow-sm"> <div className="flex max-w-lg rounded-md shadow-sm">
<Field <Field id="webhookUrl" name="webhookUrl" type="text" />
id="webhookUrl"
name="webhookUrl"
type="text"
placeholder={intl.formatMessage(
messages.webhookUrlPlaceholder
)}
/>
</div> </div>
{errors.webhookUrl && touched.webhookUrl && ( {errors.webhookUrl && touched.webhookUrl && (
<div className="error">{errors.webhookUrl}</div> <div className="error">{errors.webhookUrl}</div>

@ -14,19 +14,19 @@ const messages = defineMessages({
save: 'Save Changes', save: 'Save Changes',
saving: 'Saving…', saving: 'Saving…',
agentenabled: 'Enable Agent', agentenabled: 'Enable Agent',
botAPI: 'Bot API', botAPI: 'Bot Authentication Token',
chatId: 'Chat ID', chatId: 'Chat ID',
validationBotAPIRequired: 'You must provide a Bot API key.', validationBotAPIRequired: 'You must provide a bot authentication token',
validationChatIdRequired: 'You must provide a Chat ID.', validationChatIdRequired: 'You must provide a valid chat ID',
telegramsettingssaved: 'Telegram notification settings saved!', telegramsettingssaved: 'Telegram notification settings saved successfully!',
telegramsettingsfailed: 'Telegram notification settings failed to save.', telegramsettingsfailed: 'Telegram notification settings failed to save.',
testsent: 'Test notification sent!', testsent: 'Test notification sent!',
test: 'Test', test: 'Test',
settinguptelegram: 'Setting Up Telegram Notifications', settinguptelegram: 'Setting Up Telegram Notifications',
settinguptelegramDescription: settinguptelegramDescription:
'To configure Telegram notifications, you need to <CreateBotLink>create a bot</CreateBotLink> and get the bot API key.\ 'To configure Telegram notifications, you will need to <CreateBotLink>create a bot</CreateBotLink> and get the bot API key.\
Additionally, you need the chat ID for the chat where you would like the bot to send notifications.\ Additionally, you will need the chat ID for the chat to which you would like to send notifications.\
You can get this by adding <GetIdBotLink>@get_id_bot</GetIdBotLink> to the chat or group chat.', You can get this by adding <GetIdBotLink>@get_id_bot</GetIdBotLink> to the chat.',
notificationtypes: 'Notification Types', notificationtypes: 'Notification Types',
sendSilently: 'Send Silently', sendSilently: 'Send Silently',
sendSilentlyTip: 'Send notifications with no sound', sendSilentlyTip: 'Send notifications with no sound',
@ -43,9 +43,9 @@ const NotificationsTelegram: React.FC = () => {
botAPI: Yup.string().required( botAPI: Yup.string().required(
intl.formatMessage(messages.validationBotAPIRequired) intl.formatMessage(messages.validationBotAPIRequired)
), ),
chatId: Yup.string().required( chatId: Yup.string()
intl.formatMessage(messages.validationChatIdRequired) .required(intl.formatMessage(messages.validationChatIdRequired))
), .matches(/^\d+$/, intl.formatMessage(messages.validationChatIdRequired)),
}); });
if (!data && !error) { if (!data && !error) {

@ -40,16 +40,15 @@ const messages = defineMessages({
agentenabled: 'Enable Agent', agentenabled: 'Enable Agent',
webhookUrl: 'Webhook URL', webhookUrl: 'Webhook URL',
authheader: 'Authorization Header', authheader: 'Authorization Header',
validationJsonPayloadRequired: 'You must provide a JSON Payload', validationJsonPayloadRequired: 'You must provide a valid JSON payload',
webhookUrlPlaceholder: 'Remote webhook URL', webhooksettingssaved: 'Webhook notification settings saved successfully!',
webhooksettingssaved: 'Webhook notification settings saved!',
webhooksettingsfailed: 'Webhook notification settings failed to save.', webhooksettingsfailed: 'Webhook notification settings failed to save.',
testsent: 'Test notification sent!', testsent: 'Test notification sent!',
test: 'Test', test: 'Test',
notificationtypes: 'Notification Types', notificationtypes: 'Notification Types',
resetPayload: 'Reset to Default JSON Payload', resetPayload: 'Reset to Default',
resetPayloadSuccess: 'JSON reset to default payload.', resetPayloadSuccess: 'JSON payload reset successfully!',
customJson: 'Custom JSON Payload', customJson: 'JSON Payload',
templatevariablehelp: 'Template Variable Help', templatevariablehelp: 'Template Variable Help',
validationWebhookUrl: 'You must provide a valid URL', validationWebhookUrl: 'You must provide a valid URL',
}); });
@ -71,14 +70,18 @@ const NotificationsWebhook: React.FC = () => {
), ),
jsonPayload: Yup.string() jsonPayload: Yup.string()
.required(intl.formatMessage(messages.validationJsonPayloadRequired)) .required(intl.formatMessage(messages.validationJsonPayloadRequired))
.test('validate-json', 'Invalid JSON', (value) => { .test(
try { 'validate-json',
JSON.parse(value ?? ''); intl.formatMessage(messages.validationJsonPayloadRequired),
return true; (value) => {
} catch (e) { try {
return false; JSON.parse(value ?? '');
return true;
} catch (e) {
return false;
}
} }
}), ),
}); });
if (!data && !error) { if (!data && !error) {
@ -173,14 +176,7 @@ const NotificationsWebhook: React.FC = () => {
</label> </label>
<div className="form-input"> <div className="form-input">
<div className="flex max-w-lg rounded-md shadow-sm"> <div className="flex max-w-lg rounded-md shadow-sm">
<Field <Field id="webhookUrl" name="webhookUrl" type="text" />
id="webhookUrl"
name="webhookUrl"
type="text"
placeholder={intl.formatMessage(
messages.webhookUrlPlaceholder
)}
/>
</div> </div>
{errors.webhookUrl && touched.webhookUrl && ( {errors.webhookUrl && touched.webhookUrl && (
<div className="error">{errors.webhookUrl}</div> <div className="error">{errors.webhookUrl}</div>

@ -25,10 +25,12 @@ const messages = defineMessages({
notificationAgentsSettings: 'Notification Agents', notificationAgentsSettings: 'Notification Agents',
notificationAgentSettingsDescription: notificationAgentSettingsDescription:
'Choose the types of notifications to send, and which notification agents to use.', 'Choose the types of notifications to send, and which notification agents to use.',
notificationsettingssaved: 'Notification settings saved!', notificationsettingssaved: 'Notification settings saved successfully!',
notificationsettingsfailed: 'Notification settings failed to save.', notificationsettingsfailed: 'Notification settings failed to save.',
enablenotifications: 'Enable Notifications', enablenotifications: 'Enable Notifications',
autoapprovedrequests: 'Enable Notifications for Automatic Approvals', autoapprovedrequests: 'Enable Notifications for Automatic Approvals',
email: 'Email',
webhook: 'Webhook',
}); });
interface SettingsRoute { interface SettingsRoute {
@ -38,107 +40,106 @@ interface SettingsRoute {
regex: RegExp; regex: RegExp;
} }
const settingsRoutes: SettingsRoute[] = [
{
text: 'Email',
content: (
<span className="flex items-center">
<svg
className="h-4 mr-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M16 12a4 4 0 10-8 0 4 4 0 008 0zm0 0v1.5a2.5 2.5 0 005 0V12a9 9 0 10-9 9m4.5-1.206a8.959 8.959 0 01-4.5 1.207"
/>
</svg>
Email
</span>
),
route: '/settings/notifications/email',
regex: /^\/settings\/notifications\/email/,
},
{
text: 'Discord',
content: (
<span className="flex items-center">
<DiscordLogo className="h-4 mr-2" />
Discord
</span>
),
route: '/settings/notifications/discord',
regex: /^\/settings\/notifications\/discord/,
},
{
text: 'Slack',
content: (
<span className="flex items-center">
<SlackLogo className="h-4 mr-2" />
Slack
</span>
),
route: '/settings/notifications/slack',
regex: /^\/settings\/notifications\/slack/,
},
{
text: 'Telegram',
content: (
<span className="flex items-center">
<TelegramLogo className="h-4 mr-2" />
Telegram
</span>
),
route: '/settings/notifications/telegram',
regex: /^\/settings\/notifications\/telegram/,
},
{
text: 'Pushbullet',
content: (
<span className="flex items-center">
<PushbulletLogo className="h-4 mr-2" />
Pushbullet
</span>
),
route: '/settings/notifications/pushbullet',
regex: /^\/settings\/notifications\/pushbullet/,
},
{
text: 'Pushover',
content: (
<span className="flex items-center">
<PushoverLogo className="h-4 mr-2" />
Pushover
</span>
),
route: '/settings/notifications/pushover',
regex: /^\/settings\/notifications\/pushover/,
},
{
text: 'Webhook',
content: (
<span className="flex items-center">
<Bolt className="h-4 mr-2" />
Webhook
</span>
),
route: '/settings/notifications/webhook',
regex: /^\/settings\/notifications\/webhook/,
},
];
const SettingsNotifications: React.FC = ({ children }) => { const SettingsNotifications: React.FC = ({ children }) => {
const router = useRouter(); const router = useRouter();
const intl = useIntl(); const intl = useIntl();
const { addToast } = useToasts(); const { addToast } = useToasts();
const { data, error, revalidate } = useSWR('/api/v1/settings/notifications'); const { data, error, revalidate } = useSWR('/api/v1/settings/notifications');
const activeLinkColor = 'bg-indigo-700'; const settingsRoutes: SettingsRoute[] = [
{
text: intl.formatMessage(messages.email),
content: (
<span className="flex items-center">
<svg
className="h-4 mr-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M16 12a4 4 0 10-8 0 4 4 0 008 0zm0 0v1.5a2.5 2.5 0 005 0V12a9 9 0 10-9 9m4.5-1.206a8.959 8.959 0 01-4.5 1.207"
/>
</svg>
{intl.formatMessage(messages.email)}
</span>
),
route: '/settings/notifications/email',
regex: /^\/settings\/notifications\/email/,
},
{
text: 'Discord',
content: (
<span className="flex items-center">
<DiscordLogo className="h-4 mr-2" />
Discord
</span>
),
route: '/settings/notifications/discord',
regex: /^\/settings\/notifications\/discord/,
},
{
text: 'Pushbullet',
content: (
<span className="flex items-center">
<PushbulletLogo className="h-4 mr-2" />
Pushbullet
</span>
),
route: '/settings/notifications/pushbullet',
regex: /^\/settings\/notifications\/pushbullet/,
},
{
text: 'Pushover',
content: (
<span className="flex items-center">
<PushoverLogo className="h-4 mr-2" />
Pushover
</span>
),
route: '/settings/notifications/pushover',
regex: /^\/settings\/notifications\/pushover/,
},
{
text: 'Slack',
content: (
<span className="flex items-center">
<SlackLogo className="h-4 mr-2" />
Slack
</span>
),
route: '/settings/notifications/slack',
regex: /^\/settings\/notifications\/slack/,
},
{
text: 'Telegram',
content: (
<span className="flex items-center">
<TelegramLogo className="h-4 mr-2" />
Telegram
</span>
),
route: '/settings/notifications/telegram',
regex: /^\/settings\/notifications\/telegram/,
},
{
text: intl.formatMessage(messages.webhook),
content: (
<span className="flex items-center">
<Bolt className="h-4 mr-2" />
{intl.formatMessage(messages.webhook)}
</span>
),
route: '/settings/notifications/webhook',
regex: /^\/settings\/notifications\/webhook/,
},
];
const activeLinkColor = 'bg-indigo-700';
const inactiveLinkColor = 'bg-gray-800'; const inactiveLinkColor = 'bg-gray-800';
const SettingsLink: React.FC<{ const SettingsLink: React.FC<{

@ -88,17 +88,17 @@
"components.MovieDetails.viewfullcrew": "View Full Crew", "components.MovieDetails.viewfullcrew": "View Full Crew",
"components.MovieDetails.watchtrailer": "Watch Trailer", "components.MovieDetails.watchtrailer": "Watch Trailer",
"components.NotificationTypeSelector.mediaapproved": "Media Approved", "components.NotificationTypeSelector.mediaapproved": "Media Approved",
"components.NotificationTypeSelector.mediaapprovedDescription": "Sends a notification when media is approved.", "components.NotificationTypeSelector.mediaapprovedDescription": "Sends a notification when media is approved. By default, automatically approved requests will not trigger notifications.",
"components.NotificationTypeSelector.mediaavailable": "Media Available", "components.NotificationTypeSelector.mediaavailable": "Media Available",
"components.NotificationTypeSelector.mediaavailableDescription": "Sends a notification when media becomes available.", "components.NotificationTypeSelector.mediaavailableDescription": "Sends a notification when media becomes available.",
"components.NotificationTypeSelector.mediadeclined": "Media Declined", "components.NotificationTypeSelector.mediadeclined": "Media Declined",
"components.NotificationTypeSelector.mediadeclinedDescription": "Sends a notification when a request is declined.", "components.NotificationTypeSelector.mediadeclinedDescription": "Sends a notification when a request is declined.",
"components.NotificationTypeSelector.mediafailed": "Media Failed", "components.NotificationTypeSelector.mediafailed": "Media Failed",
"components.NotificationTypeSelector.mediafailedDescription": "Sends a notification when media fails to be added to services (Radarr/Sonarr). For certain agents, this will only send the notification to admins or users with the \"Manage Requests\" permission.", "components.NotificationTypeSelector.mediafailedDescription": "Sends a notification when media fails to be added to Radarr or Sonarr.",
"components.NotificationTypeSelector.mediarequested": "Media Requested", "components.NotificationTypeSelector.mediarequested": "Media Requested",
"components.NotificationTypeSelector.mediarequestedDescription": "Sends a notification when new media is requested. For certain agents, this will only send the notification to admins or users with the \"Manage Requests\" permission.", "components.NotificationTypeSelector.mediarequestedDescription": "Sends a notification when media is requested and requires approval.",
"components.PermissionEdit.admin": "Admin", "components.PermissionEdit.admin": "Admin",
"components.PermissionEdit.adminDescription": "Full administrator access. Bypasses all permission checks.", "components.PermissionEdit.adminDescription": "Full administrator access. Bypasses all other permission checks.",
"components.PermissionEdit.advancedrequest": "Advanced Requests", "components.PermissionEdit.advancedrequest": "Advanced Requests",
"components.PermissionEdit.advancedrequestDescription": "Grants permission to use advanced request options (e.g., changing servers, profiles, or paths).", "components.PermissionEdit.advancedrequestDescription": "Grants permission to use advanced request options (e.g., changing servers, profiles, or paths).",
"components.PermissionEdit.autoapprove": "Auto-Approve", "components.PermissionEdit.autoapprove": "Auto-Approve",
@ -246,28 +246,28 @@
"components.Settings.Notifications.NotificationsPushbullet.agentEnabled": "Enable Agent", "components.Settings.Notifications.NotificationsPushbullet.agentEnabled": "Enable Agent",
"components.Settings.Notifications.NotificationsPushbullet.notificationTypes": "Notification Types", "components.Settings.Notifications.NotificationsPushbullet.notificationTypes": "Notification Types",
"components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsFailed": "Pushbullet notification settings failed to save.", "components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsFailed": "Pushbullet notification settings failed to save.",
"components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsSaved": "Pushbullet notification settings saved!", "components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsSaved": "Pushbullet notification settings saved successfully!",
"components.Settings.Notifications.NotificationsPushbullet.save": "Save Changes", "components.Settings.Notifications.NotificationsPushbullet.save": "Save Changes",
"components.Settings.Notifications.NotificationsPushbullet.saving": "Saving…", "components.Settings.Notifications.NotificationsPushbullet.saving": "Saving…",
"components.Settings.Notifications.NotificationsPushbullet.settingUpPushbullet": "Setting Up Pushbullet Notifications", "components.Settings.Notifications.NotificationsPushbullet.settingUpPushbullet": "Setting Up Pushbullet Notifications",
"components.Settings.Notifications.NotificationsPushbullet.settingUpPushbulletDescription": "To configure Pushbullet notifications, you need to <CreateAccessTokenLink>create an access token</CreateAccessTokenLink> and enter it below.", "components.Settings.Notifications.NotificationsPushbullet.settingUpPushbulletDescription": "To configure Pushbullet notifications, you will need to <CreateAccessTokenLink>create an access token</CreateAccessTokenLink> and enter it below.",
"components.Settings.Notifications.NotificationsPushbullet.test": "Test", "components.Settings.Notifications.NotificationsPushbullet.test": "Test",
"components.Settings.Notifications.NotificationsPushbullet.testSent": "Test notification sent!", "components.Settings.Notifications.NotificationsPushbullet.testSent": "Test notification sent!",
"components.Settings.Notifications.NotificationsPushbullet.validationAccessTokenRequired": "You must provide an access token", "components.Settings.Notifications.NotificationsPushbullet.validationAccessTokenRequired": "You must provide an access token",
"components.Settings.Notifications.NotificationsPushover.accessToken": "Access Token", "components.Settings.Notifications.NotificationsPushover.accessToken": "Application/API Token",
"components.Settings.Notifications.NotificationsPushover.agentenabled": "Enable Agent", "components.Settings.Notifications.NotificationsPushover.agentenabled": "Enable Agent",
"components.Settings.Notifications.NotificationsPushover.notificationtypes": "Notification Types", "components.Settings.Notifications.NotificationsPushover.notificationtypes": "Notification Types",
"components.Settings.Notifications.NotificationsPushover.pushoversettingsfailed": "Pushover notification settings failed to save.", "components.Settings.Notifications.NotificationsPushover.pushoversettingsfailed": "Pushover notification settings failed to save.",
"components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "Pushover notification settings saved!", "components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "Pushover notification settings saved successfully!",
"components.Settings.Notifications.NotificationsPushover.save": "Save Changes", "components.Settings.Notifications.NotificationsPushover.save": "Save Changes",
"components.Settings.Notifications.NotificationsPushover.saving": "Saving…", "components.Settings.Notifications.NotificationsPushover.saving": "Saving…",
"components.Settings.Notifications.NotificationsPushover.settinguppushover": "Setting Up Pushover Notifications", "components.Settings.Notifications.NotificationsPushover.settinguppushover": "Setting Up Pushover Notifications",
"components.Settings.Notifications.NotificationsPushover.settinguppushoverDescription": "To configure Pushover notifications, you need to <RegisterApplicationLink>register an application</RegisterApplicationLink> and get the access token. When setting up the application, you can use one of the icons in the <IconLink>public folder</IconLink> on GitHub. You also need the Pushover user token, which can be found on the start page when you log in.", "components.Settings.Notifications.NotificationsPushover.settinguppushoverDescription": "To configure Pushover notifications, you will need to <RegisterApplicationLink>register an application</RegisterApplicationLink> and enter the API key below. (You can use one of our <IconLink>official icons on GitHub</IconLink>.) You will need also need your user key.",
"components.Settings.Notifications.NotificationsPushover.test": "Test", "components.Settings.Notifications.NotificationsPushover.test": "Test",
"components.Settings.Notifications.NotificationsPushover.testsent": "Test notification sent!", "components.Settings.Notifications.NotificationsPushover.testsent": "Test notification sent!",
"components.Settings.Notifications.NotificationsPushover.userToken": "User Token", "components.Settings.Notifications.NotificationsPushover.userToken": "User Key",
"components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "You must provide an access token", "components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "You must provide a valid application token",
"components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "You must provide a user token", "components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "You must provide a valid user key",
"components.Settings.Notifications.NotificationsSlack.agentenabled": "Enable Agent", "components.Settings.Notifications.NotificationsSlack.agentenabled": "Enable Agent",
"components.Settings.Notifications.NotificationsSlack.notificationtypes": "Notification Types", "components.Settings.Notifications.NotificationsSlack.notificationtypes": "Notification Types",
"components.Settings.Notifications.NotificationsSlack.save": "Save Changes", "components.Settings.Notifications.NotificationsSlack.save": "Save Changes",
@ -275,40 +275,40 @@
"components.Settings.Notifications.NotificationsSlack.settingupslack": "Setting Up Slack Notifications", "components.Settings.Notifications.NotificationsSlack.settingupslack": "Setting Up Slack Notifications",
"components.Settings.Notifications.NotificationsSlack.settingupslackDescription": "To configure Slack notifications, you will need to create an <WebhookLink>Incoming Webhook</WebhookLink> integration and enter the webhook URL below.", "components.Settings.Notifications.NotificationsSlack.settingupslackDescription": "To configure Slack notifications, you will need to create an <WebhookLink>Incoming Webhook</WebhookLink> integration and enter the webhook URL below.",
"components.Settings.Notifications.NotificationsSlack.slacksettingsfailed": "Slack notification settings failed to save.", "components.Settings.Notifications.NotificationsSlack.slacksettingsfailed": "Slack notification settings failed to save.",
"components.Settings.Notifications.NotificationsSlack.slacksettingssaved": "Slack notification settings saved!", "components.Settings.Notifications.NotificationsSlack.slacksettingssaved": "Slack notification settings saved successfully!",
"components.Settings.Notifications.NotificationsSlack.test": "Test", "components.Settings.Notifications.NotificationsSlack.test": "Test",
"components.Settings.Notifications.NotificationsSlack.testsent": "Test notification sent!", "components.Settings.Notifications.NotificationsSlack.testsent": "Test notification sent!",
"components.Settings.Notifications.NotificationsSlack.validationWebhookUrl": "You must provide a valid URL", "components.Settings.Notifications.NotificationsSlack.validationWebhookUrl": "You must provide a valid URL",
"components.Settings.Notifications.NotificationsSlack.webhookUrl": "Webhook URL", "components.Settings.Notifications.NotificationsSlack.webhookUrl": "Webhook URL",
"components.Settings.Notifications.NotificationsSlack.webhookUrlPlaceholder": "Webhook URL",
"components.Settings.Notifications.NotificationsWebhook.agentenabled": "Enable Agent", "components.Settings.Notifications.NotificationsWebhook.agentenabled": "Enable Agent",
"components.Settings.Notifications.NotificationsWebhook.authheader": "Authorization Header", "components.Settings.Notifications.NotificationsWebhook.authheader": "Authorization Header",
"components.Settings.Notifications.NotificationsWebhook.customJson": "Custom JSON Payload", "components.Settings.Notifications.NotificationsWebhook.customJson": "JSON Payload",
"components.Settings.Notifications.NotificationsWebhook.notificationtypes": "Notification Types", "components.Settings.Notifications.NotificationsWebhook.notificationtypes": "Notification Types",
"components.Settings.Notifications.NotificationsWebhook.resetPayload": "Reset to Default", "components.Settings.Notifications.NotificationsWebhook.resetPayload": "Reset to Default",
"components.Settings.Notifications.NotificationsWebhook.resetPayloadSuccess": "JSON payload successfully reset.", "components.Settings.Notifications.NotificationsWebhook.resetPayloadSuccess": "JSON payload reset successfully!",
"components.Settings.Notifications.NotificationsWebhook.save": "Save Changes", "components.Settings.Notifications.NotificationsWebhook.save": "Save Changes",
"components.Settings.Notifications.NotificationsWebhook.saving": "Saving…", "components.Settings.Notifications.NotificationsWebhook.saving": "Saving…",
"components.Settings.Notifications.NotificationsWebhook.templatevariablehelp": "Template Variable Help", "components.Settings.Notifications.NotificationsWebhook.templatevariablehelp": "Template Variable Help",
"components.Settings.Notifications.NotificationsWebhook.test": "Test", "components.Settings.Notifications.NotificationsWebhook.test": "Test",
"components.Settings.Notifications.NotificationsWebhook.testsent": "Test notification sent!", "components.Settings.Notifications.NotificationsWebhook.testsent": "Test notification sent!",
"components.Settings.Notifications.NotificationsWebhook.validationJsonPayloadRequired": "You must provide a JSON payload", "components.Settings.Notifications.NotificationsWebhook.validationJsonPayloadRequired": "You must provide a valid JSON payload",
"components.Settings.Notifications.NotificationsWebhook.validationWebhookUrl": "You must provide a valid URL", "components.Settings.Notifications.NotificationsWebhook.validationWebhookUrl": "You must provide a valid URL",
"components.Settings.Notifications.NotificationsWebhook.webhookUrl": "Webhook URL", "components.Settings.Notifications.NotificationsWebhook.webhookUrl": "Webhook URL",
"components.Settings.Notifications.NotificationsWebhook.webhookUrlPlaceholder": "Remote webhook URL",
"components.Settings.Notifications.NotificationsWebhook.webhooksettingsfailed": "Webhook notification settings failed to save.", "components.Settings.Notifications.NotificationsWebhook.webhooksettingsfailed": "Webhook notification settings failed to save.",
"components.Settings.Notifications.NotificationsWebhook.webhooksettingssaved": "Webhook notification settings saved!", "components.Settings.Notifications.NotificationsWebhook.webhooksettingssaved": "Webhook notification settings saved successfully!",
"components.Settings.Notifications.agentenabled": "Enable Agent", "components.Settings.Notifications.agentenabled": "Enable Agent",
"components.Settings.Notifications.allowselfsigned": "Allow Self-Signed Certificates", "components.Settings.Notifications.allowselfsigned": "Allow Self-Signed Certificates",
"components.Settings.Notifications.authPass": "SMTP Password", "components.Settings.Notifications.authPass": "SMTP Password",
"components.Settings.Notifications.authUser": "SMTP Username", "components.Settings.Notifications.authUser": "SMTP Username",
"components.Settings.Notifications.botAPI": "Bot API", "components.Settings.Notifications.botAPI": "Bot Authentication Token",
"components.Settings.Notifications.chatId": "Chat ID", "components.Settings.Notifications.chatId": "Chat ID",
"components.Settings.Notifications.discordsettingsfailed": "Discord notification settings failed to save.", "components.Settings.Notifications.discordsettingsfailed": "Discord notification settings failed to save.",
"components.Settings.Notifications.discordsettingssaved": "Discord notification settings saved!", "components.Settings.Notifications.discordsettingssaved": "Discord notification settings saved successfully!",
"components.Settings.Notifications.emailNotificationTypesAlert": "Notification Email Recipients",
"components.Settings.Notifications.emailNotificationTypesAlertDescription": "For the \"Media Requested\" and \"Media Failed\" notification types, notifications will only be sent to users with the \"Manage Requests\" permission.",
"components.Settings.Notifications.emailsender": "Sender Address", "components.Settings.Notifications.emailsender": "Sender Address",
"components.Settings.Notifications.emailsettingsfailed": "Email notification settings failed to save.", "components.Settings.Notifications.emailsettingsfailed": "Email notification settings failed to save.",
"components.Settings.Notifications.emailsettingssaved": "Email notification settings saved!", "components.Settings.Notifications.emailsettingssaved": "Email notification settings saved successfully!",
"components.Settings.Notifications.enableSsl": "Enable SSL", "components.Settings.Notifications.enableSsl": "Enable SSL",
"components.Settings.Notifications.notificationtypes": "Notification Types", "components.Settings.Notifications.notificationtypes": "Notification Types",
"components.Settings.Notifications.save": "Save Changes", "components.Settings.Notifications.save": "Save Changes",
@ -317,16 +317,16 @@
"components.Settings.Notifications.sendSilentlyTip": "Send notifications with no sound", "components.Settings.Notifications.sendSilentlyTip": "Send notifications with no sound",
"components.Settings.Notifications.senderName": "Sender Name", "components.Settings.Notifications.senderName": "Sender Name",
"components.Settings.Notifications.settinguptelegram": "Setting Up Telegram Notifications", "components.Settings.Notifications.settinguptelegram": "Setting Up Telegram Notifications",
"components.Settings.Notifications.settinguptelegramDescription": "To configure Telegram notifications, you need to <CreateBotLink>create a bot</CreateBotLink> and get the bot API key. Additionally, you need the chat ID for the chat where you would like the bot to send notifications. You can get this by adding <GetIdBotLink>@get_id_bot</GetIdBotLink> to the chat or group chat.", "components.Settings.Notifications.settinguptelegramDescription": "To configure Telegram notifications, you will need to <CreateBotLink>create a bot</CreateBotLink> and get the bot API key. Additionally, you will need the chat ID for the chat to which you would like to send notifications. You can get this by adding <GetIdBotLink>@get_id_bot</GetIdBotLink> to the chat.",
"components.Settings.Notifications.smtpHost": "SMTP Host", "components.Settings.Notifications.smtpHost": "SMTP Host",
"components.Settings.Notifications.smtpPort": "SMTP Port", "components.Settings.Notifications.smtpPort": "SMTP Port",
"components.Settings.Notifications.ssldisabletip": "SSL should be disabled on standard TLS connections (port 587)", "components.Settings.Notifications.ssldisabletip": "SSL should be disabled on standard TLS connections (port 587)",
"components.Settings.Notifications.telegramsettingsfailed": "Telegram notification settings failed to save.", "components.Settings.Notifications.telegramsettingsfailed": "Telegram notification settings failed to save.",
"components.Settings.Notifications.telegramsettingssaved": "Telegram notification settings saved!", "components.Settings.Notifications.telegramsettingssaved": "Telegram notification settings saved successfully!",
"components.Settings.Notifications.test": "Test", "components.Settings.Notifications.test": "Test",
"components.Settings.Notifications.testsent": "Test notification sent!", "components.Settings.Notifications.testsent": "Test notification sent!",
"components.Settings.Notifications.validationBotAPIRequired": "You must provide a Bot API key", "components.Settings.Notifications.validationBotAPIRequired": "You must provide a bot authentication token",
"components.Settings.Notifications.validationChatIdRequired": "You must provide a Chat ID", "components.Settings.Notifications.validationChatIdRequired": "You must provide a valid chat ID",
"components.Settings.Notifications.validationEmail": "You must provide a valid email address", "components.Settings.Notifications.validationEmail": "You must provide a valid email address",
"components.Settings.Notifications.validationSmtpHostRequired": "You must provide an SMTP host", "components.Settings.Notifications.validationSmtpHostRequired": "You must provide an SMTP host",
"components.Settings.Notifications.validationSmtpPortRequired": "You must provide an SMTP port", "components.Settings.Notifications.validationSmtpPortRequired": "You must provide an SMTP port",
@ -491,6 +491,7 @@
"components.Settings.delete": "Delete", "components.Settings.delete": "Delete",
"components.Settings.deleteserverconfirm": "Are you sure you want to delete this server?", "components.Settings.deleteserverconfirm": "Are you sure you want to delete this server?",
"components.Settings.edit": "Edit", "components.Settings.edit": "Edit",
"components.Settings.email": "Email",
"components.Settings.enablenotifications": "Enable Notifications", "components.Settings.enablenotifications": "Enable Notifications",
"components.Settings.generalsettings": "General Settings", "components.Settings.generalsettings": "General Settings",
"components.Settings.generalsettingsDescription": "Configure global and default settings for Overseerr.", "components.Settings.generalsettingsDescription": "Configure global and default settings for Overseerr.",
@ -514,7 +515,7 @@
"components.Settings.notificationsettings": "Notification Settings", "components.Settings.notificationsettings": "Notification Settings",
"components.Settings.notificationsettingsDescription": "Configure global notification settings. The options below will apply to all notification agents.", "components.Settings.notificationsettingsDescription": "Configure global notification settings. The options below will apply to all notification agents.",
"components.Settings.notificationsettingsfailed": "Notification settings failed to save.", "components.Settings.notificationsettingsfailed": "Notification settings failed to save.",
"components.Settings.notificationsettingssaved": "Notification settings saved!", "components.Settings.notificationsettingssaved": "Notification settings saved successfully!",
"components.Settings.notrunning": "Not Running", "components.Settings.notrunning": "Not Running",
"components.Settings.originallanguage": "Discover Language", "components.Settings.originallanguage": "Discover Language",
"components.Settings.originallanguageTip": "Filter content by original language (only applies to the \"Popular\" and \"Upcoming\" categories)", "components.Settings.originallanguageTip": "Filter content by original language (only applies to the \"Popular\" and \"Upcoming\" categories)",
@ -567,6 +568,7 @@
"components.Settings.validationApplicationUrlTrailingSlash": "URL must not end in a trailing slash", "components.Settings.validationApplicationUrlTrailingSlash": "URL must not end in a trailing slash",
"components.Settings.validationHostnameRequired": "You must provide a hostname/IP", "components.Settings.validationHostnameRequired": "You must provide a hostname/IP",
"components.Settings.validationPortRequired": "You must provide a port", "components.Settings.validationPortRequired": "You must provide a port",
"components.Settings.webhook": "Webhook",
"components.Setup.configureplex": "Configure Plex", "components.Setup.configureplex": "Configure Plex",
"components.Setup.configureservices": "Configure Services", "components.Setup.configureservices": "Configure Services",
"components.Setup.continue": "Continue", "components.Setup.continue": "Continue",

Loading…
Cancel
Save