diff --git a/src/components/dashboard/users/ButtonElement.tsx b/src/components/dashboard/users/ButtonElement.tsx new file mode 100644 index 0000000000..dfde8c7399 --- /dev/null +++ b/src/components/dashboard/users/ButtonElement.tsx @@ -0,0 +1,32 @@ +import React, { FunctionComponent } from 'react'; +import globalize from '../../../scripts/globalize'; + +const createButtonElement = ({ type, className, title }) => ({ + __html: ` + ${title} + ` +}); + +type IProps = { + type?: string; + className?: string; + title?: string +} + +const ButtonElement: FunctionComponent = ({ type, className, title }: IProps) => { + return ( + + ); +}; + +export default ButtonElement; diff --git a/src/components/dashboard/users/CheckBoxElement.tsx b/src/components/dashboard/users/CheckBoxElement.tsx new file mode 100644 index 0000000000..aaa5c63f51 --- /dev/null +++ b/src/components/dashboard/users/CheckBoxElement.tsx @@ -0,0 +1,33 @@ +import React, { FunctionComponent } from 'react'; +import globalize from '../../../scripts/globalize'; + +const createCheckBoxElement = ({ type, className, title }) => ({ + __html: ` + + ${title} + ` +}); + +type IProps = { + type?: string; + className?: string; + title?: string +} + +const CheckBoxElement: FunctionComponent = ({ type, className, title }: IProps) => { + return ( + + ); +}; + +export default CheckBoxElement; diff --git a/src/components/dashboard/users/CheckBoxListItem.tsx b/src/components/dashboard/users/CheckBoxListItem.tsx new file mode 100644 index 0000000000..f6282f3635 --- /dev/null +++ b/src/components/dashboard/users/CheckBoxListItem.tsx @@ -0,0 +1,34 @@ +import React, { FunctionComponent } from 'react'; + +type IProps = { + className?: string; + Name?: string; + Id?: string; +} + +const createCheckBoxElement = ({className, Name, Id}) => ({ + __html: ` + + ${Name} + ` +}); + +const CheckBoxListItem: FunctionComponent = ({className, Name, Id}: IProps) => { + return ( + + ); +}; + +export default CheckBoxListItem; + diff --git a/src/components/dashboard/users/InputElement.tsx b/src/components/dashboard/users/InputElement.tsx new file mode 100644 index 0000000000..ffcc434191 --- /dev/null +++ b/src/components/dashboard/users/InputElement.tsx @@ -0,0 +1,34 @@ +import React, { FunctionComponent } from 'react'; +import globalize from '../../../scripts/globalize'; + +const createInputElement = ({ type, id, label, options }) => ({ + __html: `` +}); + +type IProps = { + type?: string; + id?: string; + label?: string; + options?: string +} + +const InputElement: FunctionComponent = ({ type, id, label, options }: IProps) => { + return ( + + ); +}; + +export default InputElement; diff --git a/src/components/dashboard/users/SectionTitleLinkElement.tsx b/src/components/dashboard/users/SectionTitleLinkElement.tsx index 98c12c3c2d..ee1f8125c1 100644 --- a/src/components/dashboard/users/SectionTitleLinkElement.tsx +++ b/src/components/dashboard/users/SectionTitleLinkElement.tsx @@ -1,7 +1,7 @@ import React, { FunctionComponent } from 'react'; import globalize from '../../../scripts/globalize'; -const createLinkElement = ({ className, href, title }) => ({ +const createLinkElement = ({ className, title, href }) => ({ __html: ` { + const [ channelsItems, setChannelsItems ] = useState([]); + const [ mediaFoldersItems, setMediaFoldersItems ] = useState([]); + const element = useRef(null); + + const getItemsResult = (items: ItemsArr[]) => { + return items.map(item => + ({ + Id: item.Id, + Name: item.Name + }) + ); + }; + + const loadMediaFolders = useCallback((result) => { + const mediaFolders = getItemsResult(result); + + setMediaFoldersItems(mediaFolders); + + const folderAccess = element?.current?.querySelector('.folderAccess'); + folderAccess.dispatchEvent(new CustomEvent('create')); + + element.current.querySelector('.chkEnableAllFolders').checked = false; + }, []); + + const loadChannels = useCallback((result) => { + const channels = getItemsResult(result); + + setChannelsItems(channels); + + const channelAccess = element?.current?.querySelector('.channelAccess'); + channelAccess.dispatchEvent(new CustomEvent('create')); + + const channelAccessContainer = element?.current?.querySelector('.channelAccessContainer'); + channels.length ? channelAccessContainer.classList.remove('hide') : channelAccessContainer.classList.add('hide'); + + element.current.querySelector('.chkEnableAllChannels').checked = false; + }, []); + + const loadUser = useCallback(() => { + element.current.querySelector('#txtUsername').value = ''; + element.current.querySelector('#txtPassword').value = ''; + loading.show(); + const promiseFolders = window.ApiClient.getJSON(window.ApiClient.getUrl('Library/MediaFolders', { + IsHidden: false + })); + const promiseChannels = window.ApiClient.getJSON(window.ApiClient.getUrl('Channels')); + // eslint-disable-next-line compat/compat + Promise.all([promiseFolders, promiseChannels]).then(function (responses) { + loadMediaFolders(responses[0].Items); + loadChannels(responses[1].Items); + loading.hide(); + }); + }, [loadChannels, loadMediaFolders]); + + useEffect(() => { + loadUser(); + + const saveUser = () => { + const userInput: userInput = {}; + userInput.Name = element?.current?.querySelector('#txtUsername').value; + userInput.Password = element?.current?.querySelector('#txtPassword').value; + window.ApiClient.createUser(userInput).then(function (user) { + user.Policy.EnableAllFolders = element?.current?.querySelector('.chkEnableAllFolders').checked; + user.Policy.EnabledFolders = []; + + if (!user.Policy.EnableAllFolders) { + user.Policy.EnabledFolders = Array.prototype.filter.call(element?.current?.querySelectorAll('.chkFolder'), function (i) { + return i.checked; + }).map(function (i) { + return i.getAttribute('data-id'); + }); + } + + user.Policy.EnableAllChannels = element?.current?.querySelector('.chkEnableAllChannels').checked; + user.Policy.EnabledChannels = []; + + if (!user.Policy.EnableAllChannels) { + user.Policy.EnabledChannels = Array.prototype.filter.call(element?.current?.querySelectorAll('.chkChannel'), function (i) { + return i.checked; + }).map(function (i) { + return i.getAttribute('data-id'); + }); + } + + window.ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { + Dashboard.navigate('useredit.html?userId=' + user.Id); + }); + }, function () { + toast(globalize.translate('ErrorDefault')); + loading.hide(); + }); + }; + + const onSubmit = (e) => { + loading.show(); + saveUser(); + e.preventDefault(); + e.stopPropagation(); + return false; + }; + + element?.current?.querySelector('.chkEnableAllChannels').addEventListener('change', function (this: HTMLInputElement) { + const channelAccessListContainer = element?.current?.querySelector('.channelAccessListContainer'); + this.checked ? channelAccessListContainer.classList.add('hide') : channelAccessListContainer.classList.remove('hide'); + }); + + element?.current?.querySelector('.chkEnableAllFolders').addEventListener('change', function (this: HTMLInputElement) { + const folderAccessListContainer = element?.current?.querySelector('.folderAccessListContainer'); + this.checked ? folderAccessListContainer.classList.add('hide') : folderAccessListContainer.classList.remove('hide'); + }); + + element?.current?.querySelector('.newUserProfileForm').addEventListener('submit', onSubmit); + + element?.current?.querySelector('.button-cancel').addEventListener('click', function() { + window.history.back(); + }); + }, [loadUser]); + + return ( + + + + + + {globalize.translate('ButtonAddUser')} + + + + + + + + + + + + + + {globalize.translate('HeaderLibraryAccess')} + + + + + {globalize.translate('HeaderLibraries')} + + + {mediaFoldersItems.map(Item => ( + + ))} + + + + {globalize.translate('LibraryAccessHelp')} + + + + + {globalize.translate('HeaderChannelAccess')} + + + + + {globalize.translate('Channels')} + + + {channelsItems.map(Item => ( + + ))} + + + + {globalize.translate('ChannelAccessHelp')} + + + + + + + + + + + ); +}; + +export default NewUserPage; diff --git a/src/controllers/dashboard/users/usernew.html b/src/controllers/dashboard/users/usernew.html index 67f1f61ebc..c3f77c5e49 100644 --- a/src/controllers/dashboard/users/usernew.html +++ b/src/controllers/dashboard/users/usernew.html @@ -1,62 +1,3 @@ - - - - - - ${ButtonAddUser} - ${Help} - - - - - - - - - - - - ${HeaderLibraryAccess} - - - - ${OptionEnableAccessToAllLibraries} - - ${LibraryAccessHelp} - - - - - - - - - ${HeaderChannelAccess} - - - - ${OptionEnableAccessToAllChannels} - - ${ChannelAccessHelp} - - - - - - - - - - ${Save} - - - - ${ButtonCancel} - - - - - diff --git a/src/controllers/dashboard/users/usernew.js b/src/controllers/dashboard/users/usernew.js deleted file mode 100644 index 406bf55c86..0000000000 --- a/src/controllers/dashboard/users/usernew.js +++ /dev/null @@ -1,130 +0,0 @@ -import 'jquery'; -import loading from '../../../components/loading/loading'; -import globalize from '../../../scripts/globalize'; -import '../../../elements/emby-checkbox/emby-checkbox'; -import Dashboard from '../../../scripts/clientUtils'; -import toast from '../../../components/toast/toast'; - -/* eslint-disable indent */ - - function loadMediaFolders(page, mediaFolders) { - let html = ''; - html += '' + globalize.translate('HeaderLibraries') + ''; - html += ''; - - for (let i = 0; i < mediaFolders.length; i++) { - const folder = mediaFolders[i]; - html += '' + folder.Name + ''; - } - - html += ''; - $('.folderAccess', page).html(html).trigger('create'); - $('#chkEnableAllFolders', page).prop('checked', false); - } - - function loadChannels(page, channels) { - let html = ''; - html += '' + globalize.translate('Channels') + ''; - html += ''; - - for (let i = 0; i < channels.length; i++) { - const folder = channels[i]; - html += '' + folder.Name + ''; - } - - html += ''; - $('.channelAccess', page).show().html(html).trigger('create'); - - if (channels.length) { - $('.channelAccessContainer', page).show(); - } else { - $('.channelAccessContainer', page).hide(); - } - - $('#chkEnableAllChannels', page).prop('checked', false); - } - - function loadUser(page) { - $('#txtUsername', page).val(''); - $('#txtPassword', page).val(''); - loading.show(); - const promiseFolders = ApiClient.getJSON(ApiClient.getUrl('Library/MediaFolders', { - IsHidden: false - })); - const promiseChannels = ApiClient.getJSON(ApiClient.getUrl('Channels')); - Promise.all([promiseFolders, promiseChannels]).then(function (responses) { - loadMediaFolders(page, responses[0].Items); - loadChannels(page, responses[1].Items); - loading.hide(); - }); - } - - function saveUser(page) { - const user = {}; - user.Name = $('#txtUsername', page).val(); - user.Password = $('#txtPassword', page).val(); - ApiClient.createUser(user).then(function (user) { - user.Policy.EnableAllFolders = $('#chkEnableAllFolders', page).is(':checked'); - user.Policy.EnabledFolders = []; - - if (!user.Policy.EnableAllFolders) { - user.Policy.EnabledFolders = $('.chkFolder', page).get().filter(function (i) { - return i.checked; - }).map(function (i) { - return i.getAttribute('data-id'); - }); - } - - user.Policy.EnableAllChannels = $('#chkEnableAllChannels', page).is(':checked'); - user.Policy.EnabledChannels = []; - - if (!user.Policy.EnableAllChannels) { - user.Policy.EnabledChannels = $('.chkChannel', page).get().filter(function (i) { - return i.checked; - }).map(function (i) { - return i.getAttribute('data-id'); - }); - } - - ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { - Dashboard.navigate('useredit.html?userId=' + user.Id); - }); - }, function () { - toast(globalize.translate('ErrorDefault')); - loading.hide(); - }); - } - - function onSubmit() { - const page = $(this).parents('.page')[0]; - loading.show(); - saveUser(page); - return false; - } - - function loadData(page) { - loadUser(page); - } - - $(document).on('pageinit', '#newUserPage', function () { - const page = this; - $('#chkEnableAllChannels', page).on('change', function () { - if (this.checked) { - $('.channelAccessListContainer', page).hide(); - } else { - $('.channelAccessListContainer', page).show(); - } - }); - $('#chkEnableAllFolders', page).on('change', function () { - if (this.checked) { - $('.folderAccessListContainer', page).hide(); - } else { - $('.folderAccessListContainer', page).show(); - } - }); - $('.newUserProfileForm').off('submit', onSubmit).on('submit', onSubmit); - }).on('pageshow', '#newUserPage', function () { - loadData(this); - }); - -/* eslint-enable indent */ diff --git a/src/scripts/routes.js b/src/scripts/routes.js index ed0b40b97d..68b47cc75c 100644 --- a/src/scripts/routes.js +++ b/src/scripts/routes.js @@ -456,7 +456,7 @@ import { appRouter } from '../components/appRouter'; path: 'dashboard/users/usernew.html', autoFocus: false, roles: 'admin', - controller: 'dashboard/users/usernew' + pageComponent: 'NewUserPage' }); defineRoute({