diff --git a/src/components/DashboardComponent/users/ElementComponent/ButtonElement.tsx b/src/components/DashboardComponent/users/ElementComponent/ButtonElement.tsx new file mode 100644 index 0000000000..14a9ecb1e4 --- /dev/null +++ b/src/components/DashboardComponent/users/ElementComponent/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/DashboardComponent/users/ElementComponent/CheckBoxElement.tsx b/src/components/DashboardComponent/users/ElementComponent/CheckBoxElement.tsx new file mode 100644 index 0000000000..27ed0c0ebb --- /dev/null +++ b/src/components/DashboardComponent/users/ElementComponent/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/DashboardComponent/users/ElementComponent/InputElement.tsx b/src/components/DashboardComponent/users/ElementComponent/InputElement.tsx new file mode 100644 index 0000000000..127a633c69 --- /dev/null +++ b/src/components/DashboardComponent/users/ElementComponent/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, ...rest }: IProps) => { + return ( + + ); +}; + +export default InputElement; diff --git a/src/components/DashboardComponent/users/ElementComponent/SectionTitleLinkElement.tsx b/src/components/DashboardComponent/users/ElementComponent/SectionTitleLinkElement.tsx new file mode 100644 index 0000000000..68dc565796 --- /dev/null +++ b/src/components/DashboardComponent/users/ElementComponent/SectionTitleLinkElement.tsx @@ -0,0 +1,34 @@ +import React, { FunctionComponent } from 'react'; +import globalize from '../../../../scripts/globalize'; + +const createLinkElement = ({ className, title, href }) => ({ + __html: ` + ${title} + ` +}); + +type IProps = { + title?: string; + className?: string; + url?: string +} + +const SectionTitleLinkElement: FunctionComponent = ({ className, title, url }: IProps) => { + return ( + + ); +}; + +export default SectionTitleLinkElement; diff --git a/src/components/DashboardComponent/users/NewUserPage/ChannelAccess.tsx b/src/components/DashboardComponent/users/NewUserPage/ChannelAccess.tsx new file mode 100644 index 0000000000..08ac859967 --- /dev/null +++ b/src/components/DashboardComponent/users/NewUserPage/ChannelAccess.tsx @@ -0,0 +1,32 @@ +import React, { FunctionComponent } from 'react'; + +const createCheckBoxElement = ({Name, Id}) => ({ + __html: ` + + ${Name} + ` +}); + +type IProps = { + Name?: string; + Id?: string; +} + +const ChannelAccess: FunctionComponent = ({Name, Id}: IProps) => { + return ( + + ); +}; + +export default ChannelAccess; + diff --git a/src/components/DashboardComponent/users/NewUserPage/FolderAccess.tsx b/src/components/DashboardComponent/users/NewUserPage/FolderAccess.tsx new file mode 100644 index 0000000000..d5371ee8f1 --- /dev/null +++ b/src/components/DashboardComponent/users/NewUserPage/FolderAccess.tsx @@ -0,0 +1,32 @@ +import React, { FunctionComponent } from 'react'; + +const createCheckBoxElement = ({Name, Id}) => ({ + __html: ` + + ${Name} + ` +}); + +type IProps = { + Name?: string; + Id?: string; +} + +const FolderAccess: FunctionComponent = ({Name, Id}: IProps) => { + return ( + + ); +}; + +export default FolderAccess; + diff --git a/src/components/pages/NewUserPage.tsx b/src/components/pages/NewUserPage.tsx new file mode 100644 index 0000000000..f27f73391a --- /dev/null +++ b/src/components/pages/NewUserPage.tsx @@ -0,0 +1,241 @@ +import React, { FunctionComponent, useEffect, useState, useRef } from 'react'; + +import Dashboard from '../../scripts/clientUtils'; +import globalize from '../../scripts/globalize'; +import loading from '../loading/loading'; +import toast from '../toast/toast'; + +import SectionTitleLinkElement from '../DashboardComponent/users/ElementComponent/SectionTitleLinkElement'; +import InputElement from '../DashboardComponent/users/ElementComponent/InputElement'; +import CheckBoxElement from '../DashboardComponent/users/ElementComponent/CheckBoxElement'; +import FolderAccess from '../DashboardComponent/users/NewUserPage/FolderAccess'; +import ChannelAccess from '../DashboardComponent/users/NewUserPage/ChannelAccess'; +import ButtonElement from '../DashboardComponent/users/ElementComponent/ButtonElement'; + +type userInput = { + Name?: string; + Password?: string; +} + +const NewUserPage: FunctionComponent = () => { + const [ channelsResult, setChannelsResult ] = useState([]); + const [ mediaFoldersResult, setMediaFoldersResult ] = useState([]); + const element = useRef(null); + + useEffect(() => { + const loadUser = () => { + 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(); + }); + }; + + loadUser(); + + const loadMediaFolders = (mediaFolders) => { + setMediaFoldersResult(mediaFolders); + + const folderAccess = element?.current?.querySelector('.folderAccess'); + folderAccess.dispatchEvent(new CustomEvent('create')); + + element.current.querySelector('.chkEnableAllFolders').checked = false; + }; + + const loadChannels = (channels) => { + setChannelsResult(channels); + + const channelAccess = element?.current?.querySelector('.channelAccess'); + channelAccess.dispatchEvent(new CustomEvent('create')); + + if (channels.length) { + element?.current?.querySelector('.channelAccessContainer').classList.remove('hide'); + } else { + element?.current?.querySelector('.channelAccessContainer').classList.add('hide'); + } + + element.current.querySelector('.chkEnableAllChannels').checked = false; + }; + + 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; + }; + + const chkEnableAllChannels = element?.current?.querySelector('.chkEnableAllChannels'); + chkEnableAllChannels.addEventListener('change', function (this: HTMLInputElement) { + if (this.checked) { + element?.current?.querySelector('.channelAccessListContainer').classList.add('hide'); + } else { + element?.current?.querySelector('.channelAccessListContainer').classList.remove('hide'); + } + }); + + const chkEnableAllFolders = element?.current?.querySelector('.chkEnableAllFolders'); + chkEnableAllFolders.addEventListener('change', function (this: HTMLInputElement) { + if (this.checked) { + element?.current?.querySelector('.folderAccessListContainer').classList.add('hide'); + } else { + element?.current?.querySelector('.folderAccessListContainer').classList.remove('hide'); + } + }); + + element?.current?.querySelector('.newUserProfileForm').addEventListener('submit', onSubmit); + + element?.current?.querySelector('.button-cancel').addEventListener('click', function() { + window.history.back(); + }); + }, []); + + return ( + + + + + + {globalize.translate('ButtonAddUser')} + + + + + + + + + + + + + + {globalize.translate('HeaderLibraryAccess')} + + + + + {globalize.translate('HeaderLibraries')} + + + {mediaFoldersResult.map((folder, index: number)=> ( + + ))} + + + + {globalize.translate('LibraryAccessHelp')} + + + + + {globalize.translate('HeaderChannelAccess')} + + + + + {globalize.translate('Channels')} + + + {channelsResult.map((folder, index: number)=> ( + + ))} + + + + {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({