@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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "11.10.48",
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": "b7897ce23eafb03776e9ab9446685cd32709a00a"
220
+ "gitHead": "d52de056071bc84545249ed0dd87572e034136d8"
221
221
  }
@@ -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: any, data: any) => {
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: any, data: any) => {
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: string | number, token?: string) => {
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 React, { useState } from "react";
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({ ...modalState, isMailSent: true });
23
+ setModalState((prev) => ({ ...prev, isMailSent: true }));
24
24
  } else {
25
- setModalState({ ...modalState, error: true });
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({ ...modalState, input: value });
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 ? <S.ModalContent data-testid="recovery-modal-content">{ModalContent}</S.ModalContent> : null}
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 React, { useState } from "react";
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: () => void;
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
- window.handleErrorClick = toggleModal;
33
-
34
- const _handleEmail = (e: string) => handleEmail(e);
35
-
36
- const _handlePwd = (e: string) => handlePassword(e);
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={_handleEmail}
67
+ onChange={handleEmail}
67
68
  name="email"
68
- inversed={true}
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={_handlePwd}
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={true}
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={true}
93
+ inversed
93
94
  />
94
95
  <S.Password>
95
- <span
96
+ <button
97
+ type="button"
96
98
  onClick={toggleModal}
97
- onKeyDown={toggleModal}
98
- role="checkbox"
99
- aria-checked="false"
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
- </span>
109
+ </button>
105
110
  </S.Password>
106
111
  </S.Actions>
107
- <Button type="submit" disabled={isLoggingIn ? true : false}>
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 && settings.SSOWelcomeText.length ? (
14
- settings.SSOWelcomeText
15
- ) : (
16
- <>
17
- To start using Griddo, login with your
18
- <br />
19
- autentication platform
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 React, { useRef } from "react";
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<any>(null);
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
- setTimeout(() => {
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 }: any) => (
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={(slider) => (customSlider.current = slider)}>
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
- {/*<Banner text="Optimized images without any effort" image="/img/slider/gallery.png" />*/}
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: string;
82
+ className?: string;
61
83
  }
62
84
 
63
85
  export default LoginSlider;
@@ -1,18 +1,12 @@
1
- import React, { useEffect, useRef, useState } from "react";
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 = () => wrapperRef.current && setWrapperWidth(wrapperRef.current.clientWidth);
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
- if (wrapperRef.current) {
42
- setWrapperWidth(wrapperRef.current.clientWidth);
43
- }
44
- }, [wrapperRef]);
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 loginResponse: any = await global.login({ username: email, password, petitionId });
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: { status: number; data: any } = await languages.getLanguages(token);
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: any) => {
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); // TODO: capturar error bien
62
+ console.log(e);
63
63
  }
64
64
  };
65
65
  }
66
66
 
67
67
  function getUser(
68
- id: string | number,
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); // TODO: capturar error bien
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); // TODO: capturar error bien
165
+ console.log(e);
169
166
  return false;
170
167
  }
171
168
  };
172
169
  }
173
170
 
174
171
  function createPassword(
175
- id: string,
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 getUser("me", response.token)(dispatch, getState);
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); // TODO: capturar error bien
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 && userRoles.length) {
331
+ if (userRoles?.length) {
334
332
  userRoles.forEach((roleID: number) => {
335
- const rolePerms =
336
- roles &&
337
- roles.reduce((acc: string[], curr: IRole) => {
338
- if (curr.id === roleID) {
339
- const permissions = currentSiteInfo
340
- ? curr.permissions.sitePermissions
341
- : [...curr.permissions.globalPermissions, ...curr.permissions.sitePermissions];
342
- const keys = permissions.map((perm) => perm.key);
343
- acc = [...acc, ...keys];
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
  }
@@ -1,4 +1,4 @@
1
- import { Dispatch } from "redux";
1
+ import type { Dispatch } from "redux";
2
2
 
3
3
  const isReqOk = (reqStatus: number) => reqStatus >= 200 && reqStatus < 400;
4
4
 
@@ -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 && path.replace(/\/$/, "");
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
- (item.routesGroups &&
52
- item.routesGroups.find((subitem) => {
53
- return subitem.routes.find((subroute) => subroute.path === path);
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 React, { useState } from "react";
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): any;
86
- createPassword(id: string, params: ICreatePasswordParams): Promise<boolean>;
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(undefined, undefined, undefined, petitionId);
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({ ...state, email });
77
+ setState((prev) => ({ ...prev, email }));
78
78
  };
79
79
 
80
80
  const handlePassword = (password: string) => {
81
81
  resetError();
82
- setState({ ...state, password });
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({ ...state, rememberMe: !state.rememberMe });
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, password?: string, rememberMe?: boolean, petitionId?: string): Promise<boolean>;
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 React, { useState } from "react";
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): any;
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 getUser("me", token, false);
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 React, { useEffect, useState } from "react";
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 { IGetRoles, IRootState, ISite, IUser } from "@ax/types";
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, getUser, updateUser, isSaving, isLoading, getSites, getRoles, currentSiteInfo, token } = props;
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
- isUserInit ? getSites() : getUser("me");
32
- const siteId = isSiteView ? currentSiteInfo.id : "global";
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): any;
89
- getUser(id: string): any;
87
+ setHistoryPush(path: string): Promise<void>;
90
88
  getSites(): Promise<void>;
91
- updateUser(id: number, data: any, isProfile: boolean, isList: boolean): any;
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 React, { useState } from "react";
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
- siteSelectedRoles.roles.map((siteRoleId: number) => {
188
- const role = roles.find((role: IRole) => role.id === siteRoleId);
189
- return role && <RoleItem key={role.name} role={role} isReadOnly={true} />;
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's permissions and site access</strong>. If you proceed
306
- without selecting any permissions, the user <strong>won't have access to anything or view any content</strong>
307
- .
303
+ Before creating an account, <strong>select the user&apos;s permissions and site access</strong>. If you
304
+ proceed without selecting any permissions, the user{" "}
305
+ <strong>won&apos;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
- deleteUser(user.id).then((deleted: boolean) => {
57
- if (deleted) {
58
- setForm({ ...form, id: null });
59
- setHistoryPush(usersRoute);
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 React, { useState, useEffect } from "react";
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
- siteSelectedRoles.roles.map((siteRoleId: number) => {
313
- const role = roles.find((role: IRole) => role.id === siteRoleId);
314
- return role && <RoleItem key={role.name} role={role} isReadOnly={true} />;
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 = {