@griddo/ax 11.10.48 → 11.10.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/api/global.tsx +3 -2
- package/src/api/users.tsx +1 -1
- package/src/components/LanguageMenu/index.tsx +1 -1
- package/src/components/Login/LoginForm/RecoveryModal/index.tsx +5 -5
- package/src/components/Login/LoginForm/index.tsx +24 -19
- package/src/components/Login/LoginSSO/index.tsx +10 -12
- package/src/components/Login/LoginSlider/index.tsx +29 -7
- package/src/components/Login/index.tsx +12 -13
- package/src/containers/App/actions.tsx +18 -10
- package/src/containers/Users/actions.tsx +24 -28
- package/src/helpers/requests.tsx +1 -1
- package/src/modules/App/Routing/index.tsx +9 -11
- package/src/modules/CreatePass/index.tsx +6 -6
- package/src/modules/Login/index.tsx +6 -6
- package/src/modules/ResetPass/index.tsx +4 -5
- package/src/modules/Sites/index.tsx +4 -4
- package/src/modules/Users/Profile/index.tsx +7 -12
- package/src/modules/Users/UserCreate/index.tsx +9 -11
- package/src/modules/Users/UserEdit/index.tsx +6 -8
- package/src/modules/Users/UserForm/index.tsx +8 -9
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@griddo/ax",
|
|
3
3
|
"description": "Griddo Author Experience",
|
|
4
|
-
"version": "11.10.
|
|
4
|
+
"version": "11.10.49",
|
|
5
5
|
"authors": [
|
|
6
6
|
"Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
|
|
7
7
|
"Diego M. Béjar <diego.bejar@secuoyas.com>",
|
|
@@ -217,5 +217,5 @@
|
|
|
217
217
|
"publishConfig": {
|
|
218
218
|
"access": "public"
|
|
219
219
|
},
|
|
220
|
-
"gitHead": "
|
|
220
|
+
"gitHead": "d52de056071bc84545249ed0dd87572e034136d8"
|
|
221
221
|
}
|
package/src/api/global.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ICreatePasswordParams } from "@ax/types";
|
|
1
2
|
import { template } from "./config";
|
|
2
3
|
import { IServiceConfig, sendRequest } from "./utils";
|
|
3
4
|
|
|
@@ -53,7 +54,7 @@ const forgotPassword = async (user: string) => {
|
|
|
53
54
|
return sendRequest(SERVICES.FORGOT_PASSWORD);
|
|
54
55
|
};
|
|
55
56
|
|
|
56
|
-
const resetPassword = async (userID:
|
|
57
|
+
const resetPassword = async (userID: string, data: ICreatePasswordParams) => {
|
|
57
58
|
const {
|
|
58
59
|
host,
|
|
59
60
|
endpoint: [prefix, suffix],
|
|
@@ -64,7 +65,7 @@ const resetPassword = async (userID: any, data: any) => {
|
|
|
64
65
|
return sendRequest(SERVICES.RESET_PASSWORD, { ...data });
|
|
65
66
|
};
|
|
66
67
|
|
|
67
|
-
const createPassword = async (userID:
|
|
68
|
+
const createPassword = async (userID: number, data: ICreatePasswordParams) => {
|
|
68
69
|
const {
|
|
69
70
|
host,
|
|
70
71
|
endpoint: [prefix, suffix],
|
package/src/api/users.tsx
CHANGED
|
@@ -85,7 +85,7 @@ const getSiteUsers = async (params: any, siteID: number) => {
|
|
|
85
85
|
return sendRequest(SERVICES.GET_SITE_USERS);
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
const getUser = async (id:
|
|
88
|
+
const getUser = async (id: number, token?: string) => {
|
|
89
89
|
const { host, endpoint } = SERVICES.GET_USER;
|
|
90
90
|
|
|
91
91
|
SERVICES.GET_USER.dynamicUrl = `${host}${endpoint}${id}`;
|
|
@@ -14,7 +14,7 @@ const LanguageMenu = (props: ILanguageMenuProps): JSX.Element => {
|
|
|
14
14
|
const getLanguageIcon = (lang: string) => {
|
|
15
15
|
const isCurrentLanguage = lang === language;
|
|
16
16
|
const isAvailableToEdit = !isCurrentLanguage && isEditableVersion(lang);
|
|
17
|
-
let iconName;
|
|
17
|
+
let iconName: string;
|
|
18
18
|
|
|
19
19
|
if (isCurrentLanguage) {
|
|
20
20
|
iconName = "done";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState } from "react";
|
|
2
2
|
|
|
3
3
|
import { global } from "@ax/api";
|
|
4
4
|
import { isReqOk, validateEmail } from "@ax/helpers";
|
|
@@ -20,9 +20,9 @@ const RecoveryModal = (props: IRecoveryProps): JSX.Element => {
|
|
|
20
20
|
const handleResetPassword = async () => {
|
|
21
21
|
const response = await global.forgotPassword(modalState.input);
|
|
22
22
|
if (isReqOk(response.status)) {
|
|
23
|
-
setModalState({ ...
|
|
23
|
+
setModalState((prev) => ({ ...prev, isMailSent: true }));
|
|
24
24
|
} else {
|
|
25
|
-
setModalState({ ...
|
|
25
|
+
setModalState((prev) => ({ ...prev, error: true }));
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -32,7 +32,7 @@ const RecoveryModal = (props: IRecoveryProps): JSX.Element => {
|
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
const handleModalChange = (value: string) => {
|
|
35
|
-
setModalState({ ...
|
|
35
|
+
setModalState((prev) => ({ ...prev, input: value }));
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
const mainAction = !modalState.isMailSent
|
|
@@ -76,7 +76,7 @@ const RecoveryModal = (props: IRecoveryProps): JSX.Element => {
|
|
|
76
76
|
mainAction={mainAction}
|
|
77
77
|
secondaryAction={secondaryAction}
|
|
78
78
|
>
|
|
79
|
-
{isOpen
|
|
79
|
+
{isOpen && <S.ModalContent data-testid="recovery-modal-content">{ModalContent}</S.ModalContent>}
|
|
80
80
|
</Modal>
|
|
81
81
|
);
|
|
82
82
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
2
|
|
|
3
|
-
import { IGlobalSettings } from "@ax/containers/App/reducer";
|
|
3
|
+
import type { IGlobalSettings } from "@ax/containers/App/reducer";
|
|
4
4
|
import { useModal } from "@ax/hooks";
|
|
5
5
|
import { Button, FieldsBehavior, ErrorToast } from "@ax/components";
|
|
6
6
|
import RecoveryModal from "./RecoveryModal";
|
|
@@ -9,7 +9,7 @@ import * as S from "./style";
|
|
|
9
9
|
|
|
10
10
|
declare global {
|
|
11
11
|
interface Window {
|
|
12
|
-
handleErrorClick
|
|
12
|
+
handleErrorClick?: () => void;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -29,11 +29,12 @@ const LoginForm = (props: ILoginFormProps): JSX.Element => {
|
|
|
29
29
|
const [viewPass, setViewPass] = useState(false);
|
|
30
30
|
const { isOpen, toggleModal } = useModal();
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
window.handleErrorClick = toggleModal;
|
|
34
|
+
return () => {
|
|
35
|
+
delete window.handleErrorClick;
|
|
36
|
+
};
|
|
37
|
+
}, [toggleModal]);
|
|
37
38
|
|
|
38
39
|
const _togglePassword = () => setViewPass(!viewPass);
|
|
39
40
|
|
|
@@ -63,9 +64,9 @@ const LoginForm = (props: ILoginFormProps): JSX.Element => {
|
|
|
63
64
|
title="Email"
|
|
64
65
|
autoComplete="email"
|
|
65
66
|
value={email}
|
|
66
|
-
onChange={
|
|
67
|
+
onChange={handleEmail}
|
|
67
68
|
name="email"
|
|
68
|
-
inversed
|
|
69
|
+
inversed
|
|
69
70
|
placeholder="Type your email"
|
|
70
71
|
/>
|
|
71
72
|
<FieldsBehavior
|
|
@@ -73,13 +74,13 @@ const LoginForm = (props: ILoginFormProps): JSX.Element => {
|
|
|
73
74
|
title="Password"
|
|
74
75
|
inputType={inputType}
|
|
75
76
|
value={password}
|
|
76
|
-
onChange={
|
|
77
|
+
onChange={handlePassword}
|
|
77
78
|
autoComplete="current-password"
|
|
78
79
|
icon={icon}
|
|
79
80
|
onClickIcon={_togglePassword}
|
|
80
81
|
iconPosition="in"
|
|
81
82
|
name="password"
|
|
82
|
-
inversed
|
|
83
|
+
inversed
|
|
83
84
|
/>
|
|
84
85
|
<S.Actions>
|
|
85
86
|
<FieldsBehavior
|
|
@@ -89,22 +90,26 @@ const LoginForm = (props: ILoginFormProps): JSX.Element => {
|
|
|
89
90
|
onChange={handleRememberMe}
|
|
90
91
|
options={[{ title: "Remember me" }]}
|
|
91
92
|
name="rememberMe"
|
|
92
|
-
inversed
|
|
93
|
+
inversed
|
|
93
94
|
/>
|
|
94
95
|
<S.Password>
|
|
95
|
-
<
|
|
96
|
+
<button
|
|
97
|
+
type="button"
|
|
96
98
|
onClick={toggleModal}
|
|
97
|
-
onKeyDown={
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
onKeyDown={(e) => {
|
|
100
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
toggleModal();
|
|
103
|
+
}
|
|
104
|
+
}}
|
|
100
105
|
tabIndex={0}
|
|
101
106
|
data-testid="forgot-button"
|
|
102
107
|
>
|
|
103
108
|
Lost your password?
|
|
104
|
-
</
|
|
109
|
+
</button>
|
|
105
110
|
</S.Password>
|
|
106
111
|
</S.Actions>
|
|
107
|
-
<Button type="submit" disabled={isLoggingIn
|
|
112
|
+
<Button type="submit" disabled={isLoggingIn}>
|
|
108
113
|
{btnText}
|
|
109
114
|
</Button>
|
|
110
115
|
<RecoveryModal isOpen={isOpen} toggleModal={toggleModal} />
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import { Icon, ErrorToast } from "@ax/components";
|
|
3
|
-
import { IGlobalSettings } from "@ax/containers/App/reducer";
|
|
2
|
+
import type { IGlobalSettings } from "@ax/containers/App/reducer";
|
|
4
3
|
|
|
5
4
|
import * as S from "./style";
|
|
6
5
|
|
|
@@ -9,16 +8,15 @@ const LoginSSO = (props: ILoginSSOProps): JSX.Element => {
|
|
|
9
8
|
|
|
10
9
|
const handleClick = () => handleSSO();
|
|
11
10
|
|
|
12
|
-
const welcomeText =
|
|
13
|
-
settings.SSOWelcomeText
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
);
|
|
11
|
+
const welcomeText = settings.SSOWelcomeText?.length ? (
|
|
12
|
+
settings.SSOWelcomeText
|
|
13
|
+
) : (
|
|
14
|
+
<>
|
|
15
|
+
To start using Griddo, login with your
|
|
16
|
+
<br />
|
|
17
|
+
autentication platform
|
|
18
|
+
</>
|
|
19
|
+
);
|
|
22
20
|
|
|
23
21
|
return (
|
|
24
22
|
<S.Wrapper>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
2
|
import Slider from "react-slick";
|
|
3
3
|
import "slick-carousel/slick/slick.css";
|
|
4
4
|
|
|
@@ -7,13 +7,30 @@ import * as S from "./style";
|
|
|
7
7
|
const LoginSlider = (props: ILoginSliderProps): JSX.Element => {
|
|
8
8
|
const { className } = props;
|
|
9
9
|
|
|
10
|
-
const customSlider = useRef<
|
|
10
|
+
const customSlider = useRef<Slider | null>(null);
|
|
11
|
+
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
12
|
+
|
|
13
|
+
const setSliderRef = (slider: Slider | null) => {
|
|
14
|
+
customSlider.current = slider;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
return () => {
|
|
19
|
+
if (timeoutRef.current) {
|
|
20
|
+
clearTimeout(timeoutRef.current);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}, []);
|
|
11
24
|
|
|
12
25
|
const beforeChange = (prev: number, next: number) => {
|
|
26
|
+
if (!customSlider.current?.innerSlider?.list) return;
|
|
27
|
+
|
|
13
28
|
const prevSlideElement = customSlider.current.innerSlider.list.querySelector(`[data-index="${prev}"]`);
|
|
14
29
|
const nextSlideElement = customSlider.current.innerSlider.list.querySelector(`[data-index="${next}"]`);
|
|
15
30
|
|
|
16
|
-
|
|
31
|
+
if (!prevSlideElement || !nextSlideElement) return;
|
|
32
|
+
|
|
33
|
+
timeoutRef.current = setTimeout(() => {
|
|
17
34
|
prevSlideElement.classList.add("prev-slide-anim");
|
|
18
35
|
nextSlideElement.classList.remove("prev-slide-anim");
|
|
19
36
|
}, 100);
|
|
@@ -33,7 +50,7 @@ const LoginSlider = (props: ILoginSliderProps): JSX.Element => {
|
|
|
33
50
|
const handleNext = () => customSlider.current?.slickNext();
|
|
34
51
|
const handlePrev = () => customSlider.current?.slickPrev();
|
|
35
52
|
|
|
36
|
-
const Banner = ({ text, image }:
|
|
53
|
+
const Banner = ({ text, image }: IBannerProps) => (
|
|
37
54
|
<S.BannerWrapper>
|
|
38
55
|
<S.Title>{text}</S.Title>
|
|
39
56
|
<S.Image image={image} />
|
|
@@ -46,18 +63,23 @@ const LoginSlider = (props: ILoginSliderProps): JSX.Element => {
|
|
|
46
63
|
<S.Arrow onClick={handlePrev} direction="left" />
|
|
47
64
|
<S.Arrow onClick={handleNext} direction="right" />
|
|
48
65
|
</S.Buttons>
|
|
49
|
-
<Slider {...settings} ref={
|
|
66
|
+
<Slider {...settings} ref={setSliderRef}>
|
|
50
67
|
<Banner text="Full independence to publish content at any time" image="/img/slider/content.png" />
|
|
51
68
|
<Banner text="Thousands of possibilities, literally" image="/img/slider/editor.png" />
|
|
52
|
-
|
|
69
|
+
<Banner text="Optimized images without any effort" image="/img/slider/gallery.png" />
|
|
53
70
|
<Banner text="Comprehensive integration with Analytics" image="/img/slider/analytics.png" />
|
|
54
71
|
</Slider>
|
|
55
72
|
</S.Wrapper>
|
|
56
73
|
);
|
|
57
74
|
};
|
|
58
75
|
|
|
76
|
+
interface IBannerProps {
|
|
77
|
+
text: string;
|
|
78
|
+
image: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
59
81
|
export interface ILoginSliderProps {
|
|
60
|
-
className
|
|
82
|
+
className?: string;
|
|
61
83
|
}
|
|
62
84
|
|
|
63
85
|
export default LoginSlider;
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
2
|
|
|
3
|
-
import { IGlobalSettings } from "@ax/containers/App/reducer";
|
|
3
|
+
import type { IGlobalSettings } from "@ax/containers/App/reducer";
|
|
4
4
|
import { Circle } from "@ax/components";
|
|
5
5
|
import LoginForm from "./LoginForm";
|
|
6
6
|
import LoginSSO from "./LoginSSO";
|
|
7
7
|
|
|
8
8
|
import * as S from "./style";
|
|
9
9
|
|
|
10
|
-
declare global {
|
|
11
|
-
interface Window {
|
|
12
|
-
handleErrorClick: () => void;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
10
|
const Login = (props: ILoginProps): JSX.Element => {
|
|
17
11
|
const {
|
|
18
12
|
handleSubmit,
|
|
@@ -34,14 +28,19 @@ const Login = (props: ILoginProps): JSX.Element => {
|
|
|
34
28
|
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
35
29
|
|
|
36
30
|
useEffect(() => {
|
|
37
|
-
const handleResize = () =>
|
|
31
|
+
const handleResize = () => {
|
|
32
|
+
if (wrapperRef.current) {
|
|
33
|
+
setWrapperWidth(wrapperRef.current.clientWidth);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
38
36
|
|
|
39
37
|
window.addEventListener("resize", handleResize, false);
|
|
38
|
+
handleResize();
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
}, [
|
|
40
|
+
return () => {
|
|
41
|
+
window.removeEventListener("resize", handleResize, false);
|
|
42
|
+
};
|
|
43
|
+
}, []);
|
|
45
44
|
|
|
46
45
|
const _handleAnimationEnd = () => handleLoginSuccess();
|
|
47
46
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { global, languages } from "@ax/api";
|
|
2
2
|
import { isReqOk } from "@ax/helpers";
|
|
3
3
|
import type { IRootState } from "@ax/types";
|
|
4
|
+
import { usersActions } from "@ax/containers/Users";
|
|
4
5
|
|
|
6
|
+
import type { AxiosResponse } from "axios";
|
|
5
7
|
import differenceInSeconds from "date-fns/differenceInSeconds";
|
|
6
8
|
import type { Dispatch } from "redux";
|
|
7
9
|
|
|
@@ -145,24 +147,30 @@ function handleError(response: any, isMultiple = false, msg?: string): (dispatch
|
|
|
145
147
|
};
|
|
146
148
|
}
|
|
147
149
|
|
|
148
|
-
function login(
|
|
149
|
-
email?: string
|
|
150
|
-
password?: string
|
|
151
|
-
rememberMe?: boolean
|
|
152
|
-
petitionId?: string
|
|
153
|
-
): (dispatch: Dispatch) => Promise<boolean> {
|
|
154
|
-
return async (dispatch) => {
|
|
150
|
+
function login(loginData: {
|
|
151
|
+
email?: string;
|
|
152
|
+
password?: string;
|
|
153
|
+
rememberMe?: boolean;
|
|
154
|
+
petitionId?: string;
|
|
155
|
+
}): (dispatch: Dispatch, setState: () => IRootState) => Promise<boolean> {
|
|
156
|
+
return async (dispatch, setState) => {
|
|
155
157
|
dispatch(setIsLogging(true));
|
|
156
|
-
const
|
|
158
|
+
const { email, password, rememberMe, petitionId } = loginData;
|
|
159
|
+
const loginResponse: AxiosResponse<{ id: number; token: string }> = await global.login({
|
|
160
|
+
username: email,
|
|
161
|
+
password,
|
|
162
|
+
petitionId,
|
|
163
|
+
});
|
|
157
164
|
dispatch(setIsLogging(false));
|
|
158
165
|
switch (loginResponse?.status) {
|
|
159
166
|
case 200: {
|
|
160
167
|
const {
|
|
161
|
-
data: { token },
|
|
168
|
+
data: { id, token },
|
|
162
169
|
} = loginResponse;
|
|
163
|
-
const langResponse
|
|
170
|
+
const langResponse = await languages.getLanguages(token);
|
|
164
171
|
isReqOk(langResponse.status) && dispatch(setGlobalLanguages(langResponse.data.items));
|
|
165
172
|
dispatch(setToken(loginResponse.data.token));
|
|
173
|
+
await usersActions.getUser(id, token, false)(dispatch, setState);
|
|
166
174
|
dispatch(setSessionStartedAt(new Date()));
|
|
167
175
|
dispatch(setHasAnimation(true));
|
|
168
176
|
if (rememberMe) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Dispatch } from "redux";
|
|
1
|
+
import type { Dispatch } from "redux";
|
|
2
2
|
import {
|
|
3
3
|
SET_USERS,
|
|
4
4
|
SET_USER_FORM,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
SET_GLOBAL_PERMISSIONS,
|
|
9
9
|
} from "./constants";
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import type {
|
|
12
12
|
ISetUsers,
|
|
13
13
|
ISetCurrentUser,
|
|
14
14
|
ISetUserForm,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
ISetCurrentPermissions,
|
|
17
17
|
ISetGlobalPermissions,
|
|
18
18
|
} from "./interfaces";
|
|
19
|
-
import { ICreatePasswordParams, IActivateRole, IGetRoles, IRole, IUser, IRootState } from "@ax/types";
|
|
19
|
+
import type { ICreatePasswordParams, IActivateRole, IGetRoles, IRole, IUser, IRootState } from "@ax/types";
|
|
20
20
|
import { global, users, roles } from "@ax/api";
|
|
21
21
|
import { appActions } from "@ax/containers/App";
|
|
22
22
|
import { handleRequest, isReqOk } from "@ax/helpers";
|
|
@@ -51,7 +51,7 @@ function getUsers(params: any, siteID?: number | null): (dispatch: Dispatch) =>
|
|
|
51
51
|
const callback = async () => (siteID ? users.getSiteUsers(params, siteID) : users.getUsers(params));
|
|
52
52
|
|
|
53
53
|
const responseActions = {
|
|
54
|
-
handleSuccess: (response:
|
|
54
|
+
handleSuccess: (response: IUser[]) => {
|
|
55
55
|
dispatch(setUsers(response));
|
|
56
56
|
},
|
|
57
57
|
handleError: (response: any) => appActions.handleError(response)(dispatch),
|
|
@@ -59,13 +59,13 @@ function getUsers(params: any, siteID?: number | null): (dispatch: Dispatch) =>
|
|
|
59
59
|
|
|
60
60
|
await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
|
|
61
61
|
} catch (e) {
|
|
62
|
-
console.log(e);
|
|
62
|
+
console.log(e);
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function getUser(
|
|
68
|
-
id:
|
|
68
|
+
id: number,
|
|
69
69
|
token?: string,
|
|
70
70
|
hasLoading = true,
|
|
71
71
|
): (dispatch: Dispatch, getState: () => IRootState) => Promise<void> {
|
|
@@ -77,13 +77,10 @@ function getUser(
|
|
|
77
77
|
handleSuccess: (response: IUser) => {
|
|
78
78
|
if (token) {
|
|
79
79
|
dispatch(appActions.setToken(token));
|
|
80
|
-
}
|
|
81
|
-
if (id === "me") {
|
|
82
80
|
dispatch(setCurrentUser(response));
|
|
83
81
|
getUserCurrentPermissions()(dispatch, getState);
|
|
84
|
-
} else {
|
|
85
|
-
dispatch(setUserForm(response));
|
|
86
82
|
}
|
|
83
|
+
dispatch(setUserForm(response));
|
|
87
84
|
},
|
|
88
85
|
handleError: (response: any) => appActions.handleError(response)(dispatch),
|
|
89
86
|
};
|
|
@@ -92,7 +89,7 @@ function getUser(
|
|
|
92
89
|
|
|
93
90
|
await handleRequest(callback, responseActions, loading)(dispatch);
|
|
94
91
|
} catch (e) {
|
|
95
|
-
console.log(e);
|
|
92
|
+
console.log(e);
|
|
96
93
|
}
|
|
97
94
|
};
|
|
98
95
|
}
|
|
@@ -165,14 +162,14 @@ function createUser(data: { name: string; email: string }): (dispatch: Dispatch)
|
|
|
165
162
|
|
|
166
163
|
return await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
|
|
167
164
|
} catch (e) {
|
|
168
|
-
console.log(e);
|
|
165
|
+
console.log(e);
|
|
169
166
|
return false;
|
|
170
167
|
}
|
|
171
168
|
};
|
|
172
169
|
}
|
|
173
170
|
|
|
174
171
|
function createPassword(
|
|
175
|
-
id:
|
|
172
|
+
id: number,
|
|
176
173
|
params: ICreatePasswordParams,
|
|
177
174
|
): (dispatch: Dispatch, getState: () => IRootState) => Promise<boolean> {
|
|
178
175
|
return async (dispatch, getState) => {
|
|
@@ -182,14 +179,15 @@ function createPassword(
|
|
|
182
179
|
const responseActions = {
|
|
183
180
|
handleSuccess: async (response: any) => {
|
|
184
181
|
dispatch(appActions.setToken(response.token));
|
|
185
|
-
await
|
|
182
|
+
await getRoles({ siteId: "global" }, response.token, false)(dispatch);
|
|
183
|
+
await getUser(id, response.token, false)(dispatch, getState);
|
|
186
184
|
},
|
|
187
185
|
handleError: (response: any) => appActions.handleError(response)(dispatch),
|
|
188
186
|
};
|
|
189
187
|
|
|
190
188
|
return await handleRequest(callback, responseActions, [appActions.setIsSaving])(dispatch);
|
|
191
189
|
} catch (e) {
|
|
192
|
-
console.log(e);
|
|
190
|
+
console.log(e);
|
|
193
191
|
return false;
|
|
194
192
|
}
|
|
195
193
|
};
|
|
@@ -330,20 +328,18 @@ function getUserCurrentPermissions(): (dispatch: Dispatch, getState: () => IRoot
|
|
|
330
328
|
: currentUser.roles.find((roleSite) => roleSite.siteId === "global")?.roles;
|
|
331
329
|
|
|
332
330
|
let permissions: string[] = [];
|
|
333
|
-
if (userRoles
|
|
331
|
+
if (userRoles?.length) {
|
|
334
332
|
userRoles.forEach((roleID: number) => {
|
|
335
|
-
const rolePerms =
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
return acc;
|
|
346
|
-
}, []);
|
|
333
|
+
const rolePerms = roles?.reduce((acc: string[], curr: IRole) => {
|
|
334
|
+
if (curr.id === roleID) {
|
|
335
|
+
const permissions = currentSiteInfo
|
|
336
|
+
? curr.permissions.sitePermissions
|
|
337
|
+
: [...curr.permissions.globalPermissions, ...curr.permissions.sitePermissions];
|
|
338
|
+
const keys = permissions.map((perm) => perm.key);
|
|
339
|
+
acc.push(...keys);
|
|
340
|
+
}
|
|
341
|
+
return acc;
|
|
342
|
+
}, []);
|
|
347
343
|
permissions = [...permissions, ...rolePerms];
|
|
348
344
|
});
|
|
349
345
|
}
|
package/src/helpers/requests.tsx
CHANGED
|
@@ -3,13 +3,13 @@ import { connect } from "react-redux";
|
|
|
3
3
|
import { Switch, Route, matchPath } from "react-router-dom";
|
|
4
4
|
|
|
5
5
|
import { ErrorGuard } from "@ax/guards";
|
|
6
|
-
import { IRootState, IUser } from "@ax/types";
|
|
6
|
+
import type { IRootState, IUser } from "@ax/types";
|
|
7
7
|
import { appActions } from "@ax/containers/App";
|
|
8
|
-
import { publicRoutes, privateRoutes, routes, IRouter } from "@ax/routes";
|
|
9
|
-
import { ILogoutAction } from "@ax/containers/App/interfaces";
|
|
8
|
+
import { publicRoutes, privateRoutes, routes, type IRouter } from "@ax/routes";
|
|
9
|
+
import type { ILogoutAction } from "@ax/containers/App/interfaces";
|
|
10
10
|
import { ErrorPage } from "@ax/components";
|
|
11
11
|
import { usePermission } from "@ax/hooks";
|
|
12
|
-
import { IGlobalSettings } from "@ax/containers/App/reducer";
|
|
12
|
+
import type { IGlobalSettings } from "@ax/containers/App/reducer";
|
|
13
13
|
import NavMenu from "./NavMenu";
|
|
14
14
|
import PrivateRoute from "./PrivateRoute";
|
|
15
15
|
import Logout from "./Logout";
|
|
@@ -36,7 +36,7 @@ const Routing = (props: IProps) => {
|
|
|
36
36
|
}, []);
|
|
37
37
|
|
|
38
38
|
const route: IRouter | undefined = routes.find((item: IRouter) => {
|
|
39
|
-
const cleanPath = path
|
|
39
|
+
const cleanPath = path?.replace(/\/$/, "");
|
|
40
40
|
|
|
41
41
|
const match = cleanPath
|
|
42
42
|
? matchPath(cleanPath, {
|
|
@@ -48,10 +48,9 @@ const Routing = (props: IProps) => {
|
|
|
48
48
|
|
|
49
49
|
return (
|
|
50
50
|
!!match ||
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}))
|
|
51
|
+
item.routesGroups?.find((subitem) => {
|
|
52
|
+
return subitem.routes.find((subroute) => subroute.path === path);
|
|
53
|
+
})
|
|
55
54
|
);
|
|
56
55
|
});
|
|
57
56
|
|
|
@@ -89,8 +88,7 @@ const Routing = (props: IProps) => {
|
|
|
89
88
|
.map((singleRoute: IRouter, i) => (
|
|
90
89
|
<React.Fragment key={i}>
|
|
91
90
|
{getRoute(singleRoute.component, singleRoute.path, isPrivate, singleRoute.permission)}
|
|
92
|
-
{singleRoute.routesGroups
|
|
93
|
-
singleRoute.routesGroups.map((subgroup: any) => mapSubroutes(subgroup, isPrivate))}
|
|
91
|
+
{singleRoute.routesGroups?.map((subgroup: any) => mapSubroutes(subgroup, isPrivate))}
|
|
94
92
|
</React.Fragment>
|
|
95
93
|
));
|
|
96
94
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState } from "react";
|
|
2
2
|
import { useParams } from "react-router-dom";
|
|
3
3
|
import { connect } from "react-redux";
|
|
4
4
|
|
|
5
5
|
import { appActions } from "@ax/containers/App";
|
|
6
6
|
import { usersActions } from "@ax/containers/Users";
|
|
7
7
|
import { Button, FieldsBehavior, ErrorToast } from "@ax/components";
|
|
8
|
-
import { ICreatePasswordParams } from "@ax/types";
|
|
8
|
+
import type { ICreatePasswordParams } from "@ax/types";
|
|
9
9
|
|
|
10
10
|
import * as S from "./style";
|
|
11
11
|
|
|
@@ -28,14 +28,14 @@ const CreatePass = (props: IProps) => {
|
|
|
28
28
|
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
29
29
|
e.preventDefault();
|
|
30
30
|
|
|
31
|
-
const params = {
|
|
31
|
+
const params: ICreatePasswordParams = {
|
|
32
32
|
id,
|
|
33
33
|
token,
|
|
34
34
|
password: state.pass1,
|
|
35
35
|
retypedPassword: state.pass2,
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
const passCreated = await createPassword(id, params);
|
|
38
|
+
const passCreated = await createPassword(parseInt(id), params);
|
|
39
39
|
if (passCreated) {
|
|
40
40
|
setHistoryPush("/profile?init=true");
|
|
41
41
|
}
|
|
@@ -82,8 +82,8 @@ const CreatePass = (props: IProps) => {
|
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
interface IProps {
|
|
85
|
-
setHistoryPush(path: string):
|
|
86
|
-
createPassword(id:
|
|
85
|
+
setHistoryPush(path: string): Promise<void>;
|
|
86
|
+
createPassword(id: number, params: ICreatePasswordParams): Promise<boolean>;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
const mapDispatchToProps = {
|
|
@@ -37,7 +37,7 @@ const LoginModule = (props: IProps) => {
|
|
|
37
37
|
// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
|
|
38
38
|
useEffect(() => {
|
|
39
39
|
const handleLogin = async () => {
|
|
40
|
-
const isLogged = await login(
|
|
40
|
+
const isLogged = await login({ petitionId });
|
|
41
41
|
if (isLogged) {
|
|
42
42
|
setIsSuccess(true);
|
|
43
43
|
}
|
|
@@ -59,7 +59,7 @@ const LoginModule = (props: IProps) => {
|
|
|
59
59
|
|
|
60
60
|
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
61
61
|
e.preventDefault();
|
|
62
|
-
const isLogged = await login(state.email, state.password, state.rememberMe);
|
|
62
|
+
const isLogged = await login({ email: state.email, password: state.password, rememberMe: state.rememberMe });
|
|
63
63
|
if (isLogged) {
|
|
64
64
|
setIsSuccess(true);
|
|
65
65
|
}
|
|
@@ -74,12 +74,12 @@ const LoginModule = (props: IProps) => {
|
|
|
74
74
|
|
|
75
75
|
const _handleEmail = (email: string) => {
|
|
76
76
|
resetError();
|
|
77
|
-
setState({ ...
|
|
77
|
+
setState((prev) => ({ ...prev, email }));
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
const handlePassword = (password: string) => {
|
|
81
81
|
resetError();
|
|
82
|
-
setState({ ...
|
|
82
|
+
setState((prev) => ({ ...prev, password }));
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
const handleLoginSuccess = () => {
|
|
@@ -87,7 +87,7 @@ const LoginModule = (props: IProps) => {
|
|
|
87
87
|
setHistoryPush(welcomePageURI);
|
|
88
88
|
};
|
|
89
89
|
|
|
90
|
-
const _handleRememberMe = () => setState({ ...
|
|
90
|
+
const _handleRememberMe = () => setState((prev) => ({ ...prev, rememberMe: !state.rememberMe }));
|
|
91
91
|
|
|
92
92
|
return (
|
|
93
93
|
<Login
|
|
@@ -111,7 +111,7 @@ const LoginModule = (props: IProps) => {
|
|
|
111
111
|
interface IProps {
|
|
112
112
|
isLoggingIn: boolean;
|
|
113
113
|
globalSettings: IGlobalSettings;
|
|
114
|
-
login(email?: string
|
|
114
|
+
login(loginData: { email?: string; password?: string; rememberMe?: boolean; petitionId?: string }): Promise<boolean>;
|
|
115
115
|
loginSSO(): Promise<string | null>;
|
|
116
116
|
resetError(): void;
|
|
117
117
|
getGlobalSettings(): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState } from "react";
|
|
2
2
|
import { useParams } from "react-router-dom";
|
|
3
3
|
import { connect } from "react-redux";
|
|
4
4
|
|
|
@@ -6,6 +6,7 @@ import { isReqOk } from "@ax/helpers";
|
|
|
6
6
|
import { global } from "@ax/api";
|
|
7
7
|
import { appActions } from "@ax/containers/App";
|
|
8
8
|
import { Button, FieldsBehavior } from "@ax/components";
|
|
9
|
+
import type { ICreatePasswordParams } from "@ax/types";
|
|
9
10
|
|
|
10
11
|
import * as S from "./style";
|
|
11
12
|
|
|
@@ -28,7 +29,7 @@ const ResetPass = (props: IProps) => {
|
|
|
28
29
|
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
29
30
|
e.preventDefault();
|
|
30
31
|
|
|
31
|
-
const params = {
|
|
32
|
+
const params: ICreatePasswordParams = {
|
|
32
33
|
id,
|
|
33
34
|
token,
|
|
34
35
|
password: state.pass1,
|
|
@@ -39,8 +40,6 @@ const ResetPass = (props: IProps) => {
|
|
|
39
40
|
if (isReqOk(response.status) && response.data.code === 200) {
|
|
40
41
|
setHistoryPush("/login");
|
|
41
42
|
}
|
|
42
|
-
|
|
43
|
-
// TODO error and success messages
|
|
44
43
|
};
|
|
45
44
|
|
|
46
45
|
const validPasswords = state.pass1.trim() !== "" && state.pass2.trim() && state.pass1 === state.pass2;
|
|
@@ -80,7 +79,7 @@ const ResetPass = (props: IProps) => {
|
|
|
80
79
|
};
|
|
81
80
|
|
|
82
81
|
interface IProps {
|
|
83
|
-
setHistoryPush(path: string):
|
|
82
|
+
setHistoryPush(path: string): Promise<void>;
|
|
84
83
|
}
|
|
85
84
|
|
|
86
85
|
const mapDispatchToProps = {
|
|
@@ -18,12 +18,12 @@ const Sites = (props: ISitesProps): JSX.Element => {
|
|
|
18
18
|
getStructuredData,
|
|
19
19
|
setLanguage,
|
|
20
20
|
getAllDataPacks,
|
|
21
|
-
getUser,
|
|
22
21
|
globalLangs,
|
|
23
22
|
getRoles,
|
|
24
23
|
updateCurrentSearch,
|
|
25
24
|
resetCurrentData,
|
|
26
25
|
setIsLoading,
|
|
26
|
+
getUserCurrentPermissions,
|
|
27
27
|
} = props;
|
|
28
28
|
|
|
29
29
|
// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
|
|
@@ -34,7 +34,7 @@ const Sites = (props: ISitesProps): JSX.Element => {
|
|
|
34
34
|
updateCurrentSearch("");
|
|
35
35
|
resetCurrentData();
|
|
36
36
|
await getRoles({ siteId: "global" }, token, false);
|
|
37
|
-
await
|
|
37
|
+
await getUserCurrentPermissions();
|
|
38
38
|
await getStructuredData(token, null, false);
|
|
39
39
|
await getAllDataPacks();
|
|
40
40
|
|
|
@@ -72,11 +72,11 @@ interface IDispatchProps {
|
|
|
72
72
|
getStructuredData(token: string, siteId?: number | null, hasLoading?: boolean): Promise<void>;
|
|
73
73
|
setLanguage(lang: { locale: string; id: number | null }): void;
|
|
74
74
|
getAllDataPacks: () => Promise<void>;
|
|
75
|
-
getUser: (id: string, token?: string, hasLoading?: boolean) => Promise<void>;
|
|
76
75
|
getRoles: (params: IGetRoles, token?: string, hasLoading?: boolean) => Promise<void>;
|
|
77
76
|
updateCurrentSearch(query: string): Promise<void>;
|
|
78
77
|
resetCurrentData(): Promise<void>;
|
|
79
78
|
setIsLoading(isLoading: boolean): void;
|
|
79
|
+
getUserCurrentPermissions(): Promise<void>;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
export type ISitesProps = IStateProps & IDispatchProps & RouteComponentProps;
|
|
@@ -86,11 +86,11 @@ const mapDispatchToProps = {
|
|
|
86
86
|
getStructuredData: structuredDataActions.getStructuredData,
|
|
87
87
|
setLanguage: appActions.setLanguage,
|
|
88
88
|
getAllDataPacks: dataPacksActions.getAllDataPacks,
|
|
89
|
-
getUser: usersActions.getUser,
|
|
90
89
|
getRoles: usersActions.getRoles,
|
|
91
90
|
updateCurrentSearch: structuredDataActions.updateCurrentSearch,
|
|
92
91
|
resetCurrentData: structuredDataActions.resetCurrentData,
|
|
93
92
|
setIsLoading: appActions.setIsLoading,
|
|
93
|
+
getUserCurrentPermissions: usersActions.getUserCurrentPermissions,
|
|
94
94
|
};
|
|
95
95
|
|
|
96
96
|
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Sites));
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
3
|
|
|
4
4
|
import { appActions } from "@ax/containers/App";
|
|
5
5
|
import { usersActions } from "@ax/containers/Users";
|
|
6
6
|
import { sitesActions } from "@ax/containers/Sites";
|
|
7
7
|
import { Loading, MainWrapper } from "@ax/components";
|
|
8
|
-
import {
|
|
8
|
+
import type { IRootState, ISite, IUser } from "@ax/types";
|
|
9
9
|
import { useModal, useShouldBeSaved, useURLSearchParam } from "@ax/hooks";
|
|
10
10
|
|
|
11
11
|
import UserForm from "../UserForm";
|
|
12
12
|
import { LinkDeviceModal } from "./atoms";
|
|
13
13
|
|
|
14
14
|
const Profile = (props: IProps) => {
|
|
15
|
-
const { user,
|
|
15
|
+
const { user, updateUser, isSaving, isLoading, getSites, currentSiteInfo, token } = props;
|
|
16
16
|
|
|
17
17
|
if (!user) {
|
|
18
18
|
throw new Error(`ERROR: User reached Profile with null user`);
|
|
@@ -28,9 +28,8 @@ const Profile = (props: IProps) => {
|
|
|
28
28
|
|
|
29
29
|
// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
|
|
30
30
|
useEffect(() => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
getRoles({ siteId });
|
|
31
|
+
const getUserData = async () => await getSites();
|
|
32
|
+
isUserInit && getUserData();
|
|
34
33
|
}, []);
|
|
35
34
|
|
|
36
35
|
useEffect(() => {
|
|
@@ -85,19 +84,15 @@ const mapStateToProps = (state: IRootState) => ({
|
|
|
85
84
|
});
|
|
86
85
|
|
|
87
86
|
interface IDispatchProps {
|
|
88
|
-
setHistoryPush(path: string):
|
|
89
|
-
getUser(id: string): any;
|
|
87
|
+
setHistoryPush(path: string): Promise<void>;
|
|
90
88
|
getSites(): Promise<void>;
|
|
91
|
-
updateUser(id: number, data:
|
|
92
|
-
getRoles(params: IGetRoles): Promise<void>;
|
|
89
|
+
updateUser(id: number, data: IUser, isProfile: boolean, isList: boolean): Promise<boolean>;
|
|
93
90
|
}
|
|
94
91
|
|
|
95
92
|
const mapDispatchToProps = {
|
|
96
93
|
setHistoryPush: appActions.setHistoryPush,
|
|
97
|
-
getUser: usersActions.getUser,
|
|
98
94
|
updateUser: usersActions.updateUser,
|
|
99
95
|
getSites: sitesActions.getSites,
|
|
100
|
-
getRoles: usersActions.getRoles,
|
|
101
96
|
};
|
|
102
97
|
|
|
103
98
|
interface IProfileProps {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
|
-
import { ISite, IRootState, IUser, IRole, ISiteRoles } from "@ax/types";
|
|
3
|
+
import type { ISite, IRootState, IUser, IRole, ISiteRoles } from "@ax/types";
|
|
4
4
|
import { appActions } from "@ax/containers/App";
|
|
5
5
|
import { usersActions } from "@ax/containers/Users";
|
|
6
6
|
import { ErrorToast, FieldsBehavior, MainWrapper, SearchField, Notification, Button, Modal } from "@ax/components";
|
|
@@ -155,7 +155,6 @@ const UserCreate = (props: IUserCreateProps) => {
|
|
|
155
155
|
value={state.name}
|
|
156
156
|
onChange={handleNameChange}
|
|
157
157
|
autoComplete="user-name"
|
|
158
|
-
autoFocus
|
|
159
158
|
/>
|
|
160
159
|
<FieldsBehavior
|
|
161
160
|
title="Email"
|
|
@@ -183,11 +182,10 @@ const UserCreate = (props: IUserCreateProps) => {
|
|
|
183
182
|
</S.SettingContent>
|
|
184
183
|
</S.SettingsWrapper>
|
|
185
184
|
<S.RoleList data-testid="user-role-list">
|
|
186
|
-
{siteSelectedRoles
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
})}
|
|
185
|
+
{siteSelectedRoles?.roles.map((siteRoleId: number) => {
|
|
186
|
+
const role = roles.find((role: IRole) => role.id === siteRoleId);
|
|
187
|
+
return role && <RoleItem key={role.name} role={role} isReadOnly={true} />;
|
|
188
|
+
})}
|
|
191
189
|
{siteSelectedRoles && siteSelectedRoles.roles.length > 0 && (
|
|
192
190
|
<Button type="button" buttonStyle="line" onClick={toggleModal}>
|
|
193
191
|
Manage user roles
|
|
@@ -302,9 +300,9 @@ const UserCreate = (props: IUserCreateProps) => {
|
|
|
302
300
|
size="S"
|
|
303
301
|
>
|
|
304
302
|
<S.ModalContent>
|
|
305
|
-
Before creating an account, <strong>select the user
|
|
306
|
-
without selecting any permissions, the user
|
|
307
|
-
|
|
303
|
+
Before creating an account, <strong>select the user's permissions and site access</strong>. If you
|
|
304
|
+
proceed without selecting any permissions, the user{" "}
|
|
305
|
+
<strong>won't have access to anything or view any content</strong>.
|
|
308
306
|
</S.ModalContent>
|
|
309
307
|
</Modal>
|
|
310
308
|
</MainWrapper>
|
|
@@ -51,14 +51,12 @@ const UserEdit = (props: IProps) => {
|
|
|
51
51
|
action: form.roles.length === 0 && !form.isSuperAdmin ? toggleAdviseModal : handleSave,
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
const handleDelete = () => {
|
|
55
|
-
user.id
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
});
|
|
54
|
+
const handleDelete = async () => {
|
|
55
|
+
if (!user.id) return;
|
|
56
|
+
const isDeleted = await deleteUser(user.id);
|
|
57
|
+
if (isDeleted) {
|
|
58
|
+
setHistoryPush(usersRoute);
|
|
59
|
+
}
|
|
62
60
|
};
|
|
63
61
|
|
|
64
62
|
const isSameUser = currentUser && currentUser.id === user.id;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
3
|
|
|
4
4
|
import { appActions } from "@ax/containers/App";
|
|
5
5
|
import { Button, ErrorToast, FieldsBehavior, SearchField } from "@ax/components";
|
|
6
|
-
import { IImage, IRootState, IUser, ISite, IRole, ISiteRoles } from "@ax/types";
|
|
6
|
+
import type { IImage, IRootState, IUser, ISite, IRole, ISiteRoles } from "@ax/types";
|
|
7
7
|
import { useModal } from "@ax/hooks";
|
|
8
8
|
import { RouteLeavingGuard } from "@ax/guards";
|
|
9
9
|
|
|
@@ -308,12 +308,11 @@ const UserForm = (props: IProps) => {
|
|
|
308
308
|
</S.SettingContent>
|
|
309
309
|
</S.SettingsWrapper>
|
|
310
310
|
<S.RoleList>
|
|
311
|
-
{siteSelectedRoles
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
{siteSelectedRoles && siteSelectedRoles.roles.length > 0 && (
|
|
311
|
+
{siteSelectedRoles?.roles.map((siteRoleId: number) => {
|
|
312
|
+
const role = roles.find((role: IRole) => role.id === siteRoleId);
|
|
313
|
+
return role && <RoleItem key={role.name} role={role} isReadOnly={true} />;
|
|
314
|
+
})}
|
|
315
|
+
{siteSelectedRoles && siteSelectedRoles.roles.length > 0 && !isSameUser && (
|
|
317
316
|
<Button type="button" buttonStyle="line" onClick={toggleRoleModal}>
|
|
318
317
|
Manage user roles
|
|
319
318
|
</Button>
|
|
@@ -506,7 +505,7 @@ const mapStateToProps = (state: IRootState) => ({
|
|
|
506
505
|
});
|
|
507
506
|
|
|
508
507
|
interface IDispatchProps {
|
|
509
|
-
setHistoryPush(path: string): void
|
|
508
|
+
setHistoryPush(path: string): Promise<void>;
|
|
510
509
|
}
|
|
511
510
|
|
|
512
511
|
const mapDispatchToProps = {
|