diff --git a/frontend/package.json b/frontend/package.json index 9aa2d78d8e..ad01c5c44e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -49,6 +49,7 @@ "@types/node": "14.18.10", "@types/react": "17.0.39", "@types/react-dom": "17.0.11", + "@types/react-outside-click-handler": "^1.3.1", "@types/react-router-dom": "5.3.3", "@types/react-test-renderer": "17.0.1", "@types/react-timeago": "4.1.3", diff --git a/frontend/src/component/admin/auth/PasswordAuthSettings.tsx b/frontend/src/component/admin/auth/PasswordAuthSettings.tsx index 9eebaec6a1..16a7f46054 100644 --- a/frontend/src/component/admin/auth/PasswordAuthSettings.tsx +++ b/frontend/src/component/admin/auth/PasswordAuthSettings.tsx @@ -15,8 +15,8 @@ import useToast from '../../../hooks/useToast'; const PasswordAuthSettings = () => { - const { setToastData } = useToast(); - const { config } = useAuthSettings('simple'); + const { setToastData } = useToast(); + const { config } = useAuthSettings('simple'); const [disablePasswordAuth, setDisablePasswordAuth] = useState(false); const { updateSettings, errors, loading } = useAuthSettingsApi('simple') const { hasAccess } = useContext(AccessContext); @@ -24,7 +24,7 @@ const PasswordAuthSettings = () => { useEffect(() => { setDisablePasswordAuth(!!config.disabled); - }, [ config.disabled ]); + }, [ config.disabled ]); if (!hasAccess(ADMIN)) { return ( @@ -38,10 +38,10 @@ const PasswordAuthSettings = () => { setDisablePasswordAuth(!disablePasswordAuth); }; - + const onSubmit = async evt => { evt.preventDefault(); - + try { const settings: ISimpleAuthSettings = { disabled: disablePasswordAuth }; await updateSettings(settings); @@ -62,7 +62,7 @@ const PasswordAuthSettings = () => { }); setDisablePasswordAuth(config.disabled) } - + }; return ( diff --git a/frontend/src/component/user/UserProfile/UserProfile.jsx b/frontend/src/component/user/UserProfile/UserProfile.tsx similarity index 89% rename from frontend/src/component/user/UserProfile/UserProfile.jsx rename to frontend/src/component/user/UserProfile/UserProfile.tsx index 7d729a5dbe..7f7ac5101a 100644 --- a/frontend/src/component/user/UserProfile/UserProfile.jsx +++ b/frontend/src/component/user/UserProfile/UserProfile.tsx @@ -8,15 +8,20 @@ import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown'; import { useStyles } from './UserProfile.styles'; import { useCommonStyles } from '../../../common.styles'; import UserProfileContent from './UserProfileContent/UserProfileContent'; +import { IUser } from "../../../interfaces/user"; + +interface IUserProfileProps { + profile: IUser + updateSettingLocation: (field: 'locale', value: string) => void +} const UserProfile = ({ profile, location, - fetchUser, updateSettingLocation, -}) => { +}: IUserProfileProps) => { const [showProfile, setShowProfile] = useState(false); - const [currentLocale, setCurrentLocale] = useState([]); + const [currentLocale, setCurrentLocale] = useState(); const styles = useStyles(); const commonStyles = useCommonStyles(); @@ -35,8 +40,7 @@ const UserProfile = ({ ]); useEffect(() => { - fetchUser(); - const locale = navigator.language || navigator.userLanguage; + const locale = location.locale || navigator.language; let found = possibleLocales.find(l => l.toLowerCase().includes(locale.toLowerCase()) ); @@ -73,7 +77,6 @@ const UserProfile = ({ profile={profile} updateSettingLocation={updateSettingLocation} possibleLocales={possibleLocales} - location={location} setCurrentLocale={setCurrentLocale} currentLocale={currentLocale} /> @@ -85,7 +88,6 @@ const UserProfile = ({ UserProfile.propTypes = { profile: PropTypes.object, location: PropTypes.object, - fetchUser: PropTypes.func.isRequired, updateSettingLocation: PropTypes.func.isRequired, }; diff --git a/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.jsx b/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.tsx similarity index 86% rename from frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.jsx rename to frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.tsx index 61119e4ea1..1d8b63b020 100644 --- a/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.jsx +++ b/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import React, { useState } from 'react'; import ConditionallyRender from '../../../common/ConditionallyRender'; import { Paper, @@ -17,6 +17,17 @@ import EditProfile from '../EditProfile/EditProfile'; import legacyStyles from '../../user.module.scss'; import { getBasePath } from '../../../../utils/format-path'; import useUiConfig from '../../../../hooks/api/getters/useUiConfig/useUiConfig'; +import { IUser } from "../../../../interfaces/user"; + +interface IUserProfileContentProps { + showProfile: boolean + profile: IUser + possibleLocales: string[] + updateSettingLocation: (field: 'locale', value: string) => void + imageUrl: string + currentLocale?: string + setCurrentLocale: (value: string) => void +} const UserProfileContent = ({ showProfile, @@ -26,27 +37,31 @@ const UserProfileContent = ({ imageUrl, currentLocale, setCurrentLocale, -}) => { +}: IUserProfileContentProps) => { const commonStyles = useCommonStyles(); const { uiConfig } = useUiConfig(); const [updatedPassword, setUpdatedPassword] = useState(false); - const [edititingProfile, setEditingProfile] = useState(false); + const [editingProfile, setEditingProfile] = useState(false); const styles = useStyles(); - const setLocale = value => { + const setLocale = (value: string) => { updateSettingLocation('locale', value); }; + // @ts-expect-error const profileAvatarClasses = classnames(styles.avatar, { - [styles.editingAvatar]: edititingProfile, + // @ts-expect-error + [styles.editingAvatar]: editingProfile, }); + // @ts-expect-error const profileEmailClasses = classnames(styles.profileEmail, { - [styles.editingEmail]: edititingProfile, + // @ts-expect-error + [styles.editingEmail]: editingProfile, }); - const handleChange = e => { - const { value } = e.target; + const handleChange = (e: React.ChangeEvent<{ value: unknown }>) => { + const value = e.target.value as string; setCurrentLocale(value); setLocale(value); }; @@ -57,6 +72,7 @@ const UserProfileContent = ({ show={
({ - profile: state.user.get('profile'), location: state.settings ? state.settings.toJS().location : {}, }); -export default connect(mapStateToProps, mapDispatchToProps)(UserProfile); +export default connect( + mapStateToProps, + mapDispatchToProps +)(props => { + const user = useUser(); + + return ( + + ); +}); diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts index e64ab64fa1..70ea96657a 100644 --- a/frontend/src/interfaces/uiConfig.ts +++ b/frontend/src/interfaces/uiConfig.ts @@ -8,6 +8,7 @@ export interface IUiConfig { version: string; versionInfo: IVersionInfo; links: ILinks[]; + disablePasswordAuth?: boolean; } export interface IFlags { diff --git a/frontend/src/store/settings/index.js b/frontend/src/store/settings/index.js index a59ef68cbb..76ead4ed54 100644 --- a/frontend/src/store/settings/index.js +++ b/frontend/src/store/settings/index.js @@ -2,13 +2,13 @@ import { fromJS } from 'immutable'; import { UPDATE_SETTING } from './actions'; import { USER_LOGOUT, USER_LOGIN } from '../user/actions'; -import { getBasePath } from '../../utils/format-path'; +import { getBasePath } from '../../utils/format-path'; const localStorage = window.localStorage || { setItem: () => {}, getItem: () => {}, }; -const basePath =  getBasePath(); +const basePath = getBasePath(); const SETTINGS = `${basePath}:settings`; const DEFAULT = fromJS({ location: {} }); diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 1318ba7892..64ce1f2837 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2129,6 +2129,13 @@ dependencies: "@types/react" "*" +"@types/react-outside-click-handler@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/react-outside-click-handler/-/react-outside-click-handler-1.3.1.tgz#e4772ba550e1a548468203194d2615d8f06acdf9" + integrity sha512-0BNan5zIIDyO5k9LFSG+60ZxQ/0wf+LTF9BJx3oOUdOaJlZk6RCe52jRB75mlvLLJx2YLa61+NidOwBfptWMKw== + dependencies: + "@types/react" "*" + "@types/react-redux@^7.1.20": version "7.1.20" resolved "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.20.tgz"