1
0
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:
olav 2022-02-04 12:41:59 +01:00 committed by GitHub
parent c4efaf8276
commit dfe8250c26
8 changed files with 67 additions and 28 deletions

View File

@ -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",

View File

@ -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=''>

View File

@ -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,
};

View File

@ -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"

View File

@ -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}
/>
);
});

View File

@ -8,6 +8,7 @@ export interface IUiConfig {
version: string;
versionInfo: IVersionInfo;
links: ILinks[];
disablePasswordAuth?: boolean;
}
export interface IFlags {

View File

@ -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: {} });

View File

@ -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"