mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Refactoring duplicate code
This commit is contained in:
parent
b3b88cf78d
commit
9efc39f828
27 changed files with 462 additions and 516 deletions
|
@ -4,11 +4,11 @@ import Dashboard from '../../utils/dashboard';
|
|||
import globalize from '../../scripts/globalize';
|
||||
import loading from '../loading/loading';
|
||||
import toast from '../toast/toast';
|
||||
import SectionTitleContainer from '../dashboard/users/SectionTitleContainer';
|
||||
import InputElement from '../dashboard/users/InputElement';
|
||||
import CheckBoxListItem from '../dashboard/users/CheckBoxListItem';
|
||||
import ButtonElement from '../dashboard/users/ButtonElement';
|
||||
import SectionTitleContainer from '../dashboard/elements/SectionTitleContainer';
|
||||
import InputElement from '../dashboard/elements/InputElement';
|
||||
import ButtonElement from '../dashboard/elements/ButtonElement';
|
||||
import AccessContainer from '../dashboard/users/AccessContainer';
|
||||
import CheckBoxElement from '../dashboard/elements/CheckBoxElement';
|
||||
|
||||
type userInput = {
|
||||
Name?: string;
|
||||
|
@ -169,7 +169,7 @@ const NewUserPage: FunctionComponent = () => {
|
|||
|
||||
(page.querySelector('.newUserProfileForm') as HTMLFormElement).addEventListener('submit', onSubmit);
|
||||
|
||||
(page.querySelector('.button-cancel') as HTMLButtonElement).addEventListener('click', function() {
|
||||
(page.querySelector('#btnCancel') as HTMLButtonElement).addEventListener('click', function() {
|
||||
window.history.back();
|
||||
});
|
||||
}, [loadUser]);
|
||||
|
@ -177,10 +177,13 @@ const NewUserPage: FunctionComponent = () => {
|
|||
return (
|
||||
<div ref={element}>
|
||||
<div className='content-primary'>
|
||||
<SectionTitleContainer
|
||||
title={globalize.translate('HeaderAddUser')}
|
||||
titleLink='https://docs.jellyfin.org/general/server/users/'
|
||||
/>
|
||||
<div className='verticalSection'>
|
||||
<SectionTitleContainer
|
||||
title={globalize.translate('HeaderAddUser')}
|
||||
url='https://docs.jellyfin.org/general/server/users/'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<form className='newUserProfileForm'>
|
||||
<div className='inputContainer'>
|
||||
<InputElement
|
||||
|
@ -208,12 +211,11 @@ const NewUserPage: FunctionComponent = () => {
|
|||
description='LibraryAccessHelp'
|
||||
>
|
||||
{mediaFoldersItems.map(Item => (
|
||||
<CheckBoxListItem
|
||||
<CheckBoxElement
|
||||
key={Item.Id}
|
||||
className='chkFolder'
|
||||
Id={Item.Id}
|
||||
Name={Item.Name}
|
||||
checkedAttribute=''
|
||||
itemId={Item.Id}
|
||||
itemName={Item.Name}
|
||||
/>
|
||||
))}
|
||||
</AccessContainer>
|
||||
|
@ -229,12 +231,11 @@ const NewUserPage: FunctionComponent = () => {
|
|||
description='ChannelAccessHelp'
|
||||
>
|
||||
{channelsItems.map(Item => (
|
||||
<CheckBoxListItem
|
||||
<CheckBoxElement
|
||||
key={Item.Id}
|
||||
className='chkChannel'
|
||||
Id={Item.Id}
|
||||
Name={Item.Name}
|
||||
checkedAttribute=''
|
||||
itemId={Item.Id}
|
||||
itemName={Item.Name}
|
||||
/>
|
||||
))}
|
||||
</AccessContainer>
|
||||
|
@ -246,7 +247,8 @@ const NewUserPage: FunctionComponent = () => {
|
|||
/>
|
||||
<ButtonElement
|
||||
type='button'
|
||||
className='raised button-cancel block btnCancel'
|
||||
id='btnCancel'
|
||||
className='raised button-cancel block'
|
||||
title='ButtonCancel'
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -3,18 +3,17 @@ import React, { FunctionComponent, useCallback, useEffect, useState, useRef } fr
|
|||
import Dashboard from '../../utils/dashboard';
|
||||
import globalize from '../../scripts/globalize';
|
||||
import LibraryMenu from '../../scripts/libraryMenu';
|
||||
import ButtonElement from '../dashboard/users/ButtonElement';
|
||||
import CheckBoxElement from '../dashboard/users/CheckBoxElement';
|
||||
import CheckBoxListItem from '../dashboard/users/CheckBoxListItem';
|
||||
import InputElement from '../dashboard/users/InputElement';
|
||||
import ButtonElement from '../dashboard/elements/ButtonElement';
|
||||
import CheckBoxElement from '../dashboard/elements/CheckBoxElement';
|
||||
import InputElement from '../dashboard/elements/InputElement';
|
||||
import LinkEditUserPreferences from '../dashboard/users/LinkEditUserPreferences';
|
||||
import SectionTitleContainer from '../dashboard/users/SectionTitleContainer';
|
||||
import SelectElement from '../dashboard/users/SelectElement';
|
||||
import SelectSyncPlayAccessElement from '../dashboard/users/SelectSyncPlayAccessElement';
|
||||
import SectionTitleContainer from '../dashboard/elements/SectionTitleContainer';
|
||||
import SectionTabs from '../dashboard/users/SectionTabs';
|
||||
import loading from '../loading/loading';
|
||||
import toast from '../toast/toast';
|
||||
import { getParameterByName } from '../../utils/url';
|
||||
import escapeHTML from 'escape-html';
|
||||
import SelectElement from '../dashboard/elements/SelectElement';
|
||||
|
||||
type ItemsArr = {
|
||||
Name?: string;
|
||||
|
@ -22,11 +21,16 @@ type ItemsArr = {
|
|||
checkedAttribute: string
|
||||
}
|
||||
|
||||
type ProvidersArr = {
|
||||
Name?: string;
|
||||
Id?: string;
|
||||
}
|
||||
|
||||
const UserEditPage: FunctionComponent = () => {
|
||||
const [ userName, setUserName ] = useState('');
|
||||
const [ deleteFoldersAccess, setDeleteFoldersAccess ] = useState<ItemsArr[]>([]);
|
||||
const [ authProviders, setAuthProviders ] = useState([]);
|
||||
const [ passwordResetProviders, setPasswordResetProviders ] = useState([]);
|
||||
const [ authProviders, setAuthProviders ] = useState<ProvidersArr[]>([]);
|
||||
const [ passwordResetProviders, setPasswordResetProviders ] = useState<ItemsArr[]>([]);
|
||||
|
||||
const [ authenticationProviderId, setAuthenticationProviderId ] = useState('');
|
||||
const [ passwordResetProviderId, setPasswordResetProviderId ] = useState('');
|
||||
|
@ -172,7 +176,7 @@ const UserEditPage: FunctionComponent = () => {
|
|||
(page.querySelector('#txtLoginAttemptsBeforeLockout') as HTMLInputElement).value = user.Policy.LoginAttemptsBeforeLockout || '0';
|
||||
(page.querySelector('#txtMaxActiveSessions') as HTMLInputElement).value = user.Policy.MaxActiveSessions || '0';
|
||||
if (window.ApiClient.isMinServerVersion('10.6.0')) {
|
||||
(page.querySelector('#selectSyncPlayAccess') as HTMLInputElement).value = user.Policy.SyncPlayAccess;
|
||||
(page.querySelector('#selectSyncPlayAccess') as HTMLSelectElement).value = user.Policy.SyncPlayAccess;
|
||||
}
|
||||
loading.hide();
|
||||
}, [loadAuthProviders, loadPasswordResetProviders, loadDeleteFolders ]);
|
||||
|
@ -227,8 +231,8 @@ const UserEditPage: FunctionComponent = () => {
|
|||
user.Policy.RemoteClientBitrateLimit = Math.floor(1e6 * parseFloat((page.querySelector('#txtRemoteClientBitrateLimit') as HTMLInputElement).value || '0'));
|
||||
user.Policy.LoginAttemptsBeforeLockout = parseInt((page.querySelector('#txtLoginAttemptsBeforeLockout') as HTMLInputElement).value || '0');
|
||||
user.Policy.MaxActiveSessions = parseInt((page.querySelector('#txtMaxActiveSessions') as HTMLInputElement).value || '0');
|
||||
user.Policy.AuthenticationProviderId = (page.querySelector('.selectLoginProvider') as HTMLInputElement).value;
|
||||
user.Policy.PasswordResetProviderId = (page.querySelector('.selectPasswordResetProvider') as HTMLInputElement).value;
|
||||
user.Policy.AuthenticationProviderId = (page.querySelector('#selectLoginProvider') as HTMLSelectElement).value;
|
||||
user.Policy.PasswordResetProviderId = (page.querySelector('#selectPasswordResetProvider') as HTMLSelectElement).value;
|
||||
user.Policy.EnableContentDeletion = (page.querySelector('.chkEnableDeleteAllFolders') as HTMLInputElement).checked;
|
||||
user.Policy.EnableContentDeletionFromFolders = user.Policy.EnableContentDeletion ? [] : Array.prototype.filter.call(page.querySelectorAll('.chkFolder'), function (c) {
|
||||
return c.checked;
|
||||
|
@ -236,7 +240,7 @@ const UserEditPage: FunctionComponent = () => {
|
|||
return c.getAttribute('data-id');
|
||||
});
|
||||
if (window.ApiClient.isMinServerVersion('10.6.0')) {
|
||||
user.Policy.SyncPlayAccess = (page.querySelector('#selectSyncPlayAccess') as HTMLInputElement).value as SyncPlayUserAccessType;
|
||||
user.Policy.SyncPlayAccess = (page.querySelector('#selectSyncPlayAccess') as HTMLSelectElement).value as SyncPlayUserAccessType;
|
||||
}
|
||||
window.ApiClient.updateUser(user).then(function () {
|
||||
window.ApiClient.updateUserPolicy(user.Id || '', user.Policy || {}).then(function () {
|
||||
|
@ -270,18 +274,39 @@ const UserEditPage: FunctionComponent = () => {
|
|||
|
||||
(page.querySelector('.editUserProfileForm') as HTMLFormElement).addEventListener('submit', onSubmit);
|
||||
|
||||
(page.querySelector('.button-cancel') as HTMLButtonElement).addEventListener('click', function() {
|
||||
(page.querySelector('#btnCancel') as HTMLButtonElement).addEventListener('click', function() {
|
||||
window.history.back();
|
||||
});
|
||||
}, [loadData]);
|
||||
|
||||
const optionLoginProvider = authProviders.map((provider) => {
|
||||
const selected = provider.Id === authenticationProviderId || authProviders.length < 2 ? ' selected' : '';
|
||||
return `<option value="${provider.Id}"${selected}>${escapeHTML(provider.Name)}</option>`;
|
||||
});
|
||||
|
||||
const optionPasswordResetProvider = passwordResetProviders.map((provider) => {
|
||||
const selected = provider.Id === passwordResetProviderId || passwordResetProviders.length < 2 ? ' selected' : '';
|
||||
return `<option value="${provider.Id}"${selected}>${escapeHTML(provider.Name)}</option>`;
|
||||
});
|
||||
|
||||
const optionSyncPlayAccess = () => {
|
||||
let content = '';
|
||||
content += `<option value='CreateAndJoinGroups'>${globalize.translate('LabelSyncPlayAccessCreateAndJoinGroups')}</option>`;
|
||||
content += `<option value='JoinGroups'>${globalize.translate('LabelSyncPlayAccessJoinGroups')}</option>`;
|
||||
content += `<option value='None'>${globalize.translate('LabelSyncPlayAccessNone')}</option>`;
|
||||
return content;
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={element}>
|
||||
<div className='content-primary'>
|
||||
<SectionTitleContainer
|
||||
title={userName}
|
||||
titleLink='https://docs.jellyfin.org/general/server/users/'
|
||||
/>
|
||||
<div className='verticalSection'>
|
||||
<SectionTitleContainer
|
||||
title={userName}
|
||||
url='https://docs.jellyfin.org/general/server/users/'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<SectionTabs activeTab='useredit'/>
|
||||
<div
|
||||
className='lnkEditUserPreferencesContainer'
|
||||
|
@ -313,29 +338,29 @@ const UserEditPage: FunctionComponent = () => {
|
|||
</div>
|
||||
<div className='selectContainer fldSelectLoginProvider hide'>
|
||||
<SelectElement
|
||||
className= 'selectLoginProvider'
|
||||
label= 'LabelAuthProvider'
|
||||
currentProviderId={authenticationProviderId}
|
||||
providers={authProviders}
|
||||
/>
|
||||
id='selectLoginProvider'
|
||||
label='LabelAuthProvider'
|
||||
>
|
||||
{optionLoginProvider}
|
||||
</SelectElement>
|
||||
|
||||
<div className='fieldDescription'>
|
||||
{globalize.translate('AuthProviderHelp')}
|
||||
</div>
|
||||
</div>
|
||||
<div className='selectContainer fldSelectPasswordResetProvider hide'>
|
||||
<SelectElement
|
||||
className= 'selectPasswordResetProvider'
|
||||
label= 'LabelPasswordResetProvider'
|
||||
currentProviderId={passwordResetProviderId}
|
||||
providers={passwordResetProviders}
|
||||
/>
|
||||
id='selectPasswordResetProvider'
|
||||
label='LabelPasswordResetProvider'
|
||||
>
|
||||
{optionPasswordResetProvider}
|
||||
</SelectElement>
|
||||
<div className='fieldDescription'>
|
||||
{globalize.translate('PasswordResetProviderHelp')}
|
||||
</div>
|
||||
</div>
|
||||
<div className='checkboxContainer checkboxContainer-withDescription fldRemoteAccess hide'>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkRemoteAccess'
|
||||
title='AllowRemoteAccess'
|
||||
/>
|
||||
|
@ -345,7 +370,6 @@ const UserEditPage: FunctionComponent = () => {
|
|||
</div>
|
||||
<CheckBoxElement
|
||||
labelClassName='checkboxContainer'
|
||||
type='checkbox'
|
||||
className='chkIsAdmin'
|
||||
title='OptionAllowUserToManageServer'
|
||||
/>
|
||||
|
@ -355,12 +379,10 @@ const UserEditPage: FunctionComponent = () => {
|
|||
</h2>
|
||||
<div className='checkboxList paperList' style={{padding: '.5em 1em'}}>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkEnableLiveTvAccess'
|
||||
title='OptionAllowBrowsingLiveTv'
|
||||
/>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkManageLiveTv'
|
||||
title='OptionAllowManageLiveTv'
|
||||
/>
|
||||
|
@ -372,27 +394,22 @@ const UserEditPage: FunctionComponent = () => {
|
|||
</h2>
|
||||
<div className='checkboxList paperList' style={{padding: '.5em 1em'}}>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkEnableMediaPlayback'
|
||||
title='OptionAllowMediaPlayback'
|
||||
/>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkEnableAudioPlaybackTranscoding'
|
||||
title='OptionAllowAudioPlaybackTranscoding'
|
||||
/>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkEnableVideoPlaybackTranscoding'
|
||||
title='OptionAllowVideoPlaybackTranscoding'
|
||||
/>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkEnableVideoPlaybackRemuxing'
|
||||
title='OptionAllowVideoPlaybackRemuxing'
|
||||
/>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkForceRemoteSourceTranscoding'
|
||||
title='OptionForceRemoteSourceTranscoding'
|
||||
/>
|
||||
|
@ -420,11 +437,12 @@ const UserEditPage: FunctionComponent = () => {
|
|||
</div>
|
||||
<div className='verticalSection'>
|
||||
<div className='selectContainer fldSelectSyncPlayAccess'>
|
||||
<SelectSyncPlayAccessElement
|
||||
className='selectSyncPlayAccess'
|
||||
<SelectElement
|
||||
id='selectSyncPlayAccess'
|
||||
label='LabelSyncPlayAccess'
|
||||
/>
|
||||
>
|
||||
{optionSyncPlayAccess()}
|
||||
</SelectElement>
|
||||
<div className='fieldDescription'>
|
||||
{globalize.translate('SyncPlayAccessHelp')}
|
||||
</div>
|
||||
|
@ -437,18 +455,17 @@ const UserEditPage: FunctionComponent = () => {
|
|||
<div className='checkboxList paperList checkboxList-paperList'>
|
||||
<CheckBoxElement
|
||||
labelClassName='checkboxContainer'
|
||||
type='checkbox'
|
||||
className='chkEnableDeleteAllFolders'
|
||||
title='AllLibraries'
|
||||
/>
|
||||
<div className='deleteAccess'>
|
||||
{deleteFoldersAccess.map(Item => (
|
||||
<CheckBoxListItem
|
||||
<CheckBoxElement
|
||||
key={Item.Id}
|
||||
className='chkFolder'
|
||||
Id={Item.Id}
|
||||
Name={Item.Name}
|
||||
checkedAttribute={Item.checkedAttribute}
|
||||
itemId={Item.Id}
|
||||
itemName={Item.Name}
|
||||
itemCheckedAttribute={Item.checkedAttribute}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
@ -460,12 +477,10 @@ const UserEditPage: FunctionComponent = () => {
|
|||
</h2>
|
||||
<div className='checkboxList paperList' style={{padding: '.5em 1em'}}>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkEnableRemoteControlOtherUsers'
|
||||
title='OptionAllowRemoteControlOthers'
|
||||
/>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkRemoteControlSharedDevices'
|
||||
title='OptionAllowRemoteSharedDevices'
|
||||
/>
|
||||
|
@ -479,7 +494,6 @@ const UserEditPage: FunctionComponent = () => {
|
|||
</h2>
|
||||
<div className='checkboxContainer checkboxContainer-withDescription'>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkEnableDownloading'
|
||||
title='OptionAllowContentDownload'
|
||||
/>
|
||||
|
@ -489,7 +503,6 @@ const UserEditPage: FunctionComponent = () => {
|
|||
</div>
|
||||
<div className='checkboxContainer checkboxContainer-withDescription' id='fldIsEnabled'>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkDisabled'
|
||||
title='OptionDisableUser'
|
||||
/>
|
||||
|
@ -499,7 +512,6 @@ const UserEditPage: FunctionComponent = () => {
|
|||
</div>
|
||||
<div className='checkboxContainer checkboxContainer-withDescription' id='fldIsHidden'>
|
||||
<CheckBoxElement
|
||||
type='checkbox'
|
||||
className='chkIsHidden'
|
||||
title='OptionHideUser'
|
||||
/>
|
||||
|
@ -550,7 +562,8 @@ const UserEditPage: FunctionComponent = () => {
|
|||
/>
|
||||
<ButtonElement
|
||||
type='button'
|
||||
className='raised button-cancel block btnCancel'
|
||||
id='btnCancel'
|
||||
className='raised button-cancel block'
|
||||
title='ButtonCancel'
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -6,11 +6,11 @@ import libraryMenu from '../../scripts/libraryMenu';
|
|||
import globalize from '../../scripts/globalize';
|
||||
import toast from '../toast/toast';
|
||||
import SectionTabs from '../dashboard/users/SectionTabs';
|
||||
import CheckBoxListItem from '../dashboard/users/CheckBoxListItem';
|
||||
import ButtonElement from '../dashboard/users/ButtonElement';
|
||||
import ButtonElement from '../dashboard/elements/ButtonElement';
|
||||
import { getParameterByName } from '../../utils/url';
|
||||
import SectionTitleContainer from '../dashboard/users/SectionTitleContainer';
|
||||
import SectionTitleContainer from '../dashboard/elements/SectionTitleContainer';
|
||||
import AccessContainer from '../dashboard/users/AccessContainer';
|
||||
import CheckBoxElement from '../dashboard/elements/CheckBoxElement';
|
||||
|
||||
type ItemsArr = {
|
||||
Name?: string;
|
||||
|
@ -228,10 +228,12 @@ const UserLibraryAccessPage: FunctionComponent = () => {
|
|||
return (
|
||||
<div ref={element}>
|
||||
<div className='content-primary'>
|
||||
<SectionTitleContainer
|
||||
title={userName}
|
||||
titleLink='https://docs.jellyfin.org/general/server/users/'
|
||||
/>
|
||||
<div className='verticalSection'>
|
||||
<SectionTitleContainer
|
||||
title={userName}
|
||||
url='https://docs.jellyfin.org/general/server/users/'
|
||||
/>
|
||||
</div>
|
||||
<SectionTabs activeTab='userlibraryaccess'/>
|
||||
<form className='userLibraryAccessForm'>
|
||||
<AccessContainer
|
||||
|
@ -245,12 +247,12 @@ const UserLibraryAccessPage: FunctionComponent = () => {
|
|||
description='LibraryAccessHelp'
|
||||
>
|
||||
{mediaFoldersItems.map(Item => (
|
||||
<CheckBoxListItem
|
||||
<CheckBoxElement
|
||||
key={Item.Id}
|
||||
className='chkFolder'
|
||||
Id={Item.Id}
|
||||
Name={Item.Name}
|
||||
checkedAttribute={Item.checkedAttribute}
|
||||
itemId={Item.Id}
|
||||
itemName={Item.Name}
|
||||
itemCheckedAttribute={Item.checkedAttribute}
|
||||
/>
|
||||
))}
|
||||
</AccessContainer>
|
||||
|
@ -266,12 +268,12 @@ const UserLibraryAccessPage: FunctionComponent = () => {
|
|||
description='ChannelAccessHelp'
|
||||
>
|
||||
{channelsItems.map(Item => (
|
||||
<CheckBoxListItem
|
||||
<CheckBoxElement
|
||||
key={Item.Id}
|
||||
className='chkChannel'
|
||||
Id={Item.Id}
|
||||
Name={Item.Name}
|
||||
checkedAttribute={Item.checkedAttribute}
|
||||
itemId={Item.Id}
|
||||
itemName={Item.Name}
|
||||
itemCheckedAttribute={Item.checkedAttribute}
|
||||
/>
|
||||
))}
|
||||
</AccessContainer>
|
||||
|
@ -287,13 +289,13 @@ const UserLibraryAccessPage: FunctionComponent = () => {
|
|||
description='DeviceAccessHelp'
|
||||
>
|
||||
{devicesItems.map(Item => (
|
||||
<CheckBoxListItem
|
||||
<CheckBoxElement
|
||||
key={Item.Id}
|
||||
className='chkDevice'
|
||||
Id={Item.Id}
|
||||
Name={Item.Name}
|
||||
AppName={Item.AppName}
|
||||
checkedAttribute={Item.checkedAttribute}
|
||||
itemId={Item.Id}
|
||||
itemName={Item.Name}
|
||||
itemAppName={Item.AppName}
|
||||
itemCheckedAttribute={Item.checkedAttribute}
|
||||
/>
|
||||
))}
|
||||
</AccessContainer>
|
||||
|
|
|
@ -4,15 +4,15 @@ import globalize from '../../scripts/globalize';
|
|||
import LibraryMenu from '../../scripts/libraryMenu';
|
||||
import AccessScheduleList from '../dashboard/users/AccessScheduleList';
|
||||
import BlockedTagList from '../dashboard/users/BlockedTagList';
|
||||
import ButtonElement from '../dashboard/users/ButtonElement';
|
||||
import CheckBoxListItem from '../dashboard/users/CheckBoxListItem';
|
||||
import SectionTitleButtonElement from '../dashboard/users/SectionTitleButtonElement';
|
||||
import SectionTitleContainer from '../dashboard/users/SectionTitleContainer';
|
||||
import SelectMaxParentalRating from '../dashboard/users/SelectMaxParentalRating';
|
||||
import ButtonElement from '../dashboard/elements/ButtonElement';
|
||||
import SectionTitleContainer from '../dashboard/elements/SectionTitleContainer';
|
||||
import SectionTabs from '../dashboard/users/SectionTabs';
|
||||
import loading from '../loading/loading';
|
||||
import toast from '../toast/toast';
|
||||
import { getParameterByName } from '../../utils/url';
|
||||
import CheckBoxElement from '../dashboard/elements/CheckBoxElement';
|
||||
import escapeHTML from 'escape-html';
|
||||
import SelectElement from '../dashboard/elements/SelectElement';
|
||||
|
||||
type RatingsArr = {
|
||||
Name: string;
|
||||
|
@ -181,7 +181,7 @@ const UserParentalControl: FunctionComponent = () => {
|
|||
}
|
||||
}
|
||||
|
||||
(page.querySelector('.selectMaxParentalRating') as HTMLInputElement).value = ratingValue;
|
||||
(page.querySelector('#selectMaxParentalRating') as HTMLSelectElement).value = ratingValue;
|
||||
|
||||
if (user.Policy.IsAdministrator) {
|
||||
(page.querySelector('.accessScheduleSection') as HTMLDivElement).classList.add('hide');
|
||||
|
@ -226,7 +226,7 @@ const UserParentalControl: FunctionComponent = () => {
|
|||
throw new Error('Unexpected null user.Policy');
|
||||
}
|
||||
|
||||
user.Policy.MaxParentalRating = parseInt((page.querySelector('.selectMaxParentalRating') as HTMLInputElement).value || '0', 10) || null;
|
||||
user.Policy.MaxParentalRating = parseInt((page.querySelector('#selectMaxParentalRating') as HTMLSelectElement).value || '0', 10) || null;
|
||||
user.Policy.BlockUnratedItems = Array.prototype.filter.call(page.querySelectorAll('.chkUnratedItem'), function (i) {
|
||||
return i.checked;
|
||||
}).map(function (i) {
|
||||
|
@ -299,7 +299,7 @@ const UserParentalControl: FunctionComponent = () => {
|
|||
return false;
|
||||
};
|
||||
|
||||
(page.querySelector('.btnAddSchedule') as HTMLButtonElement).addEventListener('click', function () {
|
||||
(page.querySelector('#btnAddSchedule') as HTMLButtonElement).addEventListener('click', function () {
|
||||
showSchedulePopup({
|
||||
Id: 0,
|
||||
UserId: '',
|
||||
|
@ -309,28 +309,40 @@ const UserParentalControl: FunctionComponent = () => {
|
|||
}, -1);
|
||||
});
|
||||
|
||||
(page.querySelector('.btnAddBlockedTag') as HTMLButtonElement).addEventListener('click', function () {
|
||||
(page.querySelector('#btnAddBlockedTag') as HTMLButtonElement).addEventListener('click', function () {
|
||||
showBlockedTagPopup();
|
||||
});
|
||||
|
||||
(page.querySelector('.userParentalControlForm') as HTMLFormElement).addEventListener('submit', onSubmit);
|
||||
}, [loadBlockedTags, loadData, renderAccessSchedule]);
|
||||
|
||||
const optionMaxParentalRating = () => {
|
||||
let content = '';
|
||||
content += '<option value=\'\'></option>';
|
||||
for (const rating of parentalRatings) {
|
||||
content += `<option value='${rating.Value}'>${escapeHTML(rating.Name)}</option>`;
|
||||
}
|
||||
return content;
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={element}>
|
||||
<div className='content-primary'>
|
||||
<SectionTitleContainer
|
||||
title={userName}
|
||||
titleLink='https://docs.jellyfin.org/general/server/users/'
|
||||
/>
|
||||
<div className='verticalSection'>
|
||||
<SectionTitleContainer
|
||||
title={userName}
|
||||
url='https://docs.jellyfin.org/general/server/users/'
|
||||
/>
|
||||
</div>
|
||||
<SectionTabs activeTab='userparentalcontrol'/>
|
||||
<form className='userParentalControlForm'>
|
||||
<div className='selectContainer'>
|
||||
<SelectMaxParentalRating
|
||||
className= 'selectMaxParentalRating'
|
||||
label= 'LabelMaxParentalRating'
|
||||
parentalRatings={parentalRatings}
|
||||
/>
|
||||
<SelectElement
|
||||
id='selectMaxParentalRating'
|
||||
label='LabelMaxParentalRating'
|
||||
>
|
||||
{optionMaxParentalRating()}
|
||||
</SelectElement>
|
||||
<div className='fieldDescription'>
|
||||
{globalize.translate('MaxParentalRatingHelp')}
|
||||
</div>
|
||||
|
@ -342,12 +354,12 @@ const UserParentalControl: FunctionComponent = () => {
|
|||
</h3>
|
||||
<div className='checkboxList paperList' style={{ padding: '.5em 1em' }}>
|
||||
{unratedItems.map(Item => {
|
||||
return <CheckBoxListItem
|
||||
return <CheckBoxElement
|
||||
key={Item.value}
|
||||
className='chkUnratedItem'
|
||||
ItemType={Item.value}
|
||||
Name={Item.name}
|
||||
checkedAttribute={Item.checkedAttribute}
|
||||
itemType={Item.value}
|
||||
itemName={Item.name}
|
||||
itemCheckedAttribute={Item.checkedAttribute}
|
||||
/>;
|
||||
})}
|
||||
</div>
|
||||
|
@ -355,19 +367,16 @@ const UserParentalControl: FunctionComponent = () => {
|
|||
</div>
|
||||
<br />
|
||||
<div className='verticalSection' style={{marginBottom: '2em'}}>
|
||||
<div
|
||||
className='detailSectionHeader sectionTitleContainer'
|
||||
style={{display: 'flex', alignItems: 'center', paddingBottom: '1em'}}
|
||||
>
|
||||
<h2 className='sectionTitle'>
|
||||
{globalize.translate('LabelBlockContentWithTags')}
|
||||
</h2>
|
||||
<SectionTitleButtonElement
|
||||
className='fab btnAddBlockedTag submit'
|
||||
title='Add'
|
||||
icon='add'
|
||||
/>
|
||||
</div>
|
||||
<SectionTitleContainer
|
||||
SectionClassName='detailSectionHeader'
|
||||
title={globalize.translate('LabelBlockContentWithTags')}
|
||||
isBtnVisible={true}
|
||||
btnId='btnAddBlockedTag'
|
||||
btnClassName='fab submit sectionTitleButton'
|
||||
btnTitle='Add'
|
||||
btnIcon='add'
|
||||
isLinkVisible={false}
|
||||
/>
|
||||
<div className='blockedTags' style={{marginTop: '.5em'}}>
|
||||
{blockedTags.map((tag, index) => {
|
||||
return <BlockedTagList
|
||||
|
@ -378,19 +387,15 @@ const UserParentalControl: FunctionComponent = () => {
|
|||
</div>
|
||||
</div>
|
||||
<div className='accessScheduleSection verticalSection' style={{marginBottom: '2em'}}>
|
||||
<div
|
||||
className='sectionTitleContainer'
|
||||
style={{display: 'flex', alignItems: 'center', paddingBottom: '1em'}}
|
||||
>
|
||||
<h2 className='sectionTitle'>
|
||||
{globalize.translate('HeaderAccessSchedule')}
|
||||
</h2>
|
||||
<SectionTitleButtonElement
|
||||
className='fab btnAddSchedule submit'
|
||||
title='Add'
|
||||
icon='add'
|
||||
/>
|
||||
</div>
|
||||
<SectionTitleContainer
|
||||
title={globalize.translate('HeaderAccessSchedule')}
|
||||
isBtnVisible={true}
|
||||
btnId='btnAddSchedule'
|
||||
btnClassName='fab submit sectionTitleButton'
|
||||
btnTitle='Add'
|
||||
btnIcon='add'
|
||||
isLinkVisible={false}
|
||||
/>
|
||||
<p>{globalize.translate('HeaderAccessScheduleHelp')}</p>
|
||||
<div className='accessScheduleList paperList'>
|
||||
{accessSchedules.map((accessSchedule, index) => {
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { FunctionComponent, useCallback, useEffect, useState } from 'reac
|
|||
import SectionTabs from '../dashboard/users/SectionTabs';
|
||||
import UserPasswordForm from '../dashboard/users/UserPasswordForm';
|
||||
import { getParameterByName } from '../../utils/url';
|
||||
import SectionTitleContainer from '../dashboard/users/SectionTitleContainer';
|
||||
import SectionTitleContainer from '../dashboard/elements/SectionTitleContainer';
|
||||
|
||||
const UserPasswordPage: FunctionComponent = () => {
|
||||
const userId = getParameterByName('userId');
|
||||
|
@ -23,10 +23,12 @@ const UserPasswordPage: FunctionComponent = () => {
|
|||
return (
|
||||
<div>
|
||||
<div className='content-primary'>
|
||||
<SectionTitleContainer
|
||||
title={userName}
|
||||
titleLink='https://docs.jellyfin.org/general/server/users/'
|
||||
/>
|
||||
<div className='verticalSection'>
|
||||
<SectionTitleContainer
|
||||
title={userName}
|
||||
url='https://docs.jellyfin.org/general/server/users/'
|
||||
/>
|
||||
</div>
|
||||
<SectionTabs activeTab='userpassword'/>
|
||||
<div className='readOnlyContent'>
|
||||
<UserPasswordForm
|
||||
|
|
|
@ -6,7 +6,7 @@ import globalize from '../../scripts/globalize';
|
|||
import LibraryMenu from '../../scripts/libraryMenu';
|
||||
import { appHost } from '../apphost';
|
||||
import confirm from '../confirm/confirm';
|
||||
import ButtonElement from '../dashboard/users/ButtonElement';
|
||||
import ButtonElement from '../dashboard/elements/ButtonElement';
|
||||
import UserPasswordForm from '../dashboard/users/UserPasswordForm';
|
||||
import loading from '../loading/loading';
|
||||
import toast from '../toast/toast';
|
||||
|
@ -57,11 +57,11 @@ const UserProfilePage: FunctionComponent<IProps> = ({userId}: IProps) => {
|
|||
}
|
||||
|
||||
if (user.PrimaryImageTag) {
|
||||
(page.querySelector('.btnAddImage') as HTMLButtonElement).classList.add('hide');
|
||||
(page.querySelector('.btnDeleteImage') as HTMLButtonElement).classList.remove('hide');
|
||||
(page.querySelector('#btnAddImage') as HTMLButtonElement).classList.add('hide');
|
||||
(page.querySelector('#btnDeleteImage') as HTMLButtonElement).classList.remove('hide');
|
||||
} else if (appHost.supports('fileinput') && (loggedInUser?.Policy?.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) {
|
||||
(page.querySelector('.btnDeleteImage') as HTMLButtonElement).classList.add('hide');
|
||||
(page.querySelector('.btnAddImage') as HTMLButtonElement).classList.remove('hide');
|
||||
(page.querySelector('#btnDeleteImage') as HTMLButtonElement).classList.add('hide');
|
||||
(page.querySelector('#btnAddImage') as HTMLButtonElement).classList.remove('hide');
|
||||
}
|
||||
});
|
||||
loading.hide();
|
||||
|
@ -120,7 +120,7 @@ const UserProfilePage: FunctionComponent<IProps> = ({userId}: IProps) => {
|
|||
reader.readAsDataURL(file);
|
||||
};
|
||||
|
||||
(page.querySelector('.btnDeleteImage') as HTMLButtonElement).addEventListener('click', function () {
|
||||
(page.querySelector('#btnDeleteImage') as HTMLButtonElement).addEventListener('click', function () {
|
||||
confirm(
|
||||
globalize.translate('DeleteImageConfirmation'),
|
||||
globalize.translate('DeleteImage')
|
||||
|
@ -133,7 +133,7 @@ const UserProfilePage: FunctionComponent<IProps> = ({userId}: IProps) => {
|
|||
});
|
||||
});
|
||||
|
||||
(page.querySelector('.btnAddImage') as HTMLButtonElement).addEventListener('click', function () {
|
||||
(page.querySelector('#btnAddImage') as HTMLButtonElement).addEventListener('click', function () {
|
||||
const uploadImage = page.querySelector('#uploadImage') as HTMLInputElement;
|
||||
uploadImage.value = '';
|
||||
uploadImage.click();
|
||||
|
@ -172,12 +172,14 @@ const UserProfilePage: FunctionComponent<IProps> = ({userId}: IProps) => {
|
|||
<br />
|
||||
<ButtonElement
|
||||
type='button'
|
||||
className='raised btnAddImage hide'
|
||||
id='btnAddImage'
|
||||
className='raised button-submit hide'
|
||||
title='ButtonAddImage'
|
||||
/>
|
||||
<ButtonElement
|
||||
type='button'
|
||||
className='raised btnDeleteImage hide'
|
||||
id='btnDeleteImage'
|
||||
className='raised button-delete hide'
|
||||
title='DeleteImage'
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,7 @@ import loading from '../loading/loading';
|
|||
import dom from '../../scripts/dom';
|
||||
import confirm from '../../components/confirm/confirm';
|
||||
import UserCardBox from '../dashboard/users/UserCardBox';
|
||||
import SectionTitleContainer from '../dashboard/users/SectionTitleContainer';
|
||||
import SectionTitleContainer from '../dashboard/elements/SectionTitleContainer';
|
||||
import '../../elements/emby-button/emby-button';
|
||||
import '../../elements/emby-button/paper-icon-button-light';
|
||||
import '../../components/cardbuilder/card.scss';
|
||||
|
@ -124,7 +124,7 @@ const UserProfilesPage: FunctionComponent = () => {
|
|||
}
|
||||
});
|
||||
|
||||
(page.querySelector('.btnAddUser') as HTMLButtonElement).addEventListener('click', function() {
|
||||
(page.querySelector('#btnAddUser') as HTMLButtonElement).addEventListener('click', function() {
|
||||
Dashboard.navigate('usernew.html');
|
||||
});
|
||||
}, []);
|
||||
|
@ -132,11 +132,17 @@ const UserProfilesPage: FunctionComponent = () => {
|
|||
return (
|
||||
<div ref={element}>
|
||||
<div className='content-primary'>
|
||||
<SectionTitleContainer
|
||||
title={globalize.translate('HeaderUsers')}
|
||||
isBtnVisible={true}
|
||||
titleLink='https://docs.jellyfin.org/general/server/users/adding-managing-users.html'
|
||||
/>
|
||||
<div className='verticalSection'>
|
||||
<SectionTitleContainer
|
||||
title={globalize.translate('HeaderUsers')}
|
||||
isBtnVisible={true}
|
||||
btnId='btnAddUser'
|
||||
btnClassName='fab submit sectionTitleButton'
|
||||
btnTitle='ButtonAddUser'
|
||||
btnIcon='add'
|
||||
url='https://docs.jellyfin.org/general/server/users/adding-managing-users.html'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='localUsers itemsContainer vertical-wrap'>
|
||||
{users.map(user => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue