mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
refactor: port UserProfile to TS/SWR (#665)
* refactor: add missing @types/react-outside-click-handler * refactor: add missing disablePasswordAuth IUiConfig field * refactor: replace NBSPs with regular spaces * refactor: port UserProfile to TS/SWR * refactor: fix interface type prefix Co-authored-by: Fredrik Strand Oseberg <fredrik.no@gmail.com>
This commit is contained in:
parent
c4efaf8276
commit
dfe8250c26
@ -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",
|
||||
|
@ -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<boolean>(false);
|
||||
const { updateSettings, errors, loading } = useAuthSettingsApi<ISimpleAuthSettings>('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 (
|
||||
<PageContent headerContent=''>
|
||||
|
@ -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<string>();
|
||||
|
||||
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,
|
||||
};
|
||||
|
@ -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={
|
||||
<Paper
|
||||
className={classnames(
|
||||
// @ts-expect-error
|
||||
styles.profile,
|
||||
commonStyles.flexColumn,
|
||||
commonStyles.itemsCenter,
|
||||
@ -80,7 +96,7 @@ const UserProfileContent = ({
|
||||
}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={!edititingProfile}
|
||||
condition={!editingProfile}
|
||||
show={
|
||||
<>
|
||||
<ConditionallyRender condition={!uiConfig.disablePasswordAuth} show={
|
||||
@ -133,6 +149,7 @@ const UserProfileContent = ({
|
||||
</div>
|
||||
<div className={commonStyles.divider} />
|
||||
<a
|
||||
// @ts-expect-error
|
||||
className={styles.link}
|
||||
href="https://www.getunleash.io/privacy-policy"
|
||||
rel="noopener noreferrer"
|
@ -1,16 +1,27 @@
|
||||
import useUser from '../../../hooks/api/getters/useUser/useUser';
|
||||
import { connect } from 'react-redux';
|
||||
import UserProfile from './UserProfile';
|
||||
import { fetchUser } from '../../../store/user/actions';
|
||||
import { updateSettingForGroup } from '../../../store/settings/actions';
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchUser,
|
||||
updateSettingLocation: updateSettingForGroup('location'),
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
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 (
|
||||
<UserProfile
|
||||
location={props.location}
|
||||
updateSettingLocation={props.updateSettingLocation}
|
||||
profile={user.user}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -8,6 +8,7 @@ export interface IUiConfig {
|
||||
version: string;
|
||||
versionInfo: IVersionInfo;
|
||||
links: ILinks[];
|
||||
disablePasswordAuth?: boolean;
|
||||
}
|
||||
|
||||
export interface IFlags {
|
||||
|
@ -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: {} });
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user