Skip to content

Commit c8d3e3b

Browse files
authored
Merge pull request #2921 from bluewave-labs/develop
develop -> master
2 parents 7a90a6f + cb57ff5 commit c8d3e3b

File tree

20 files changed

+972
-86
lines changed

20 files changed

+972
-86
lines changed

.coderabbit.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
release_notes: false

.github/scripts/download-translations.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { URLSearchParams } from "url";
77
const API_TOKEN = process.env.POEDITOR_API;
88
const PROJECT_ID = process.env.POEDITOR_PROJECT_ID;
99
const LANGUAGES = (
10-
process.env.LANGUAGES || "ar,zh-tw,cs,en,fi,fr,de,pt-br,ru,es,tr,ja"
10+
process.env.LANGUAGES || "ar,zh-tw,cs,en,fi,fr,de,pt-br,ru,es,tr,ja,zh-cn"
1111
).split(",");
1212
const EXPORT_FORMAT = process.env.EXPORT_FORMAT || "key_value_json";
1313

.github/workflows/check-format.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616

1717
- name: Install client dependencies
1818
working-directory: client
19-
run: npm ci
19+
run: npm install
2020

2121
- name: Check client formatting
2222
working-directory: client
@@ -34,7 +34,7 @@ jobs:
3434

3535
- name: Install server dependencies
3636
working-directory: server
37-
run: npm ci
37+
run: npm install
3838

3939
- name: Check server formatting
4040
working-directory: server

.github/workflows/poeditor-sync.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
languages:
88
description: "Languages to synchronize (comma separated, e.g.: tr,en,es)"
99
required: false
10-
default: "ar,zh-tw,cs,en,fi,fr,de,pt-br,ru,es,tr,ja"
10+
default: "ar,zh-tw,cs,en,fi,fr,de,pt-br,ru,es,tr,ja,zh-cn"
1111
format:
1212
description: "Export format (key_value_json or json)"
1313
required: false

client/src/Components/Charts/StatusPageBarChart/index.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ const Bar = ({ width, height, backgroundColor, borderRadius, children }) => {
2222

2323
return (
2424
<Box
25-
position="relative"
2625
width={width}
26+
position="relative"
2727
height={height}
2828
backgroundColor={backgroundColor}
2929
sx={{
@@ -36,7 +36,7 @@ const Bar = ({ width, height, backgroundColor, borderRadius, children }) => {
3636
};
3737

3838
Bar.propTypes = {
39-
width: PropTypes.string.isRequired,
39+
width: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
4040
height: PropTypes.string.isRequired,
4141
backgroundColor: PropTypes.string.isRequired,
4242
borderRadius: PropTypes.string,

client/src/Components/Check/Check.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const Check = ({ text, noHighlightText, variant = "info", outlined = false }) =>
6565
};
6666

6767
Check.propTypes = {
68-
text: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
68+
text: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
6969
noHighlightText: PropTypes.string,
7070
variant: PropTypes.oneOf(["info", "error", "success"]),
7171
outlined: PropTypes.bool,

client/src/Components/Dialog/genericDialog.jsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useId } from "react";
22
import PropTypes from "prop-types";
33
import { Modal, Stack, Typography } from "@mui/material";
44

5-
const GenericDialog = ({ title, description, open, onClose, theme, children }) => {
5+
const GenericDialog = ({ title, description, open, onClose, theme, children, width }) => {
66
const titleId = useId();
77
const descriptionId = useId();
88
const ariaDescribedBy = description?.length > 0 ? descriptionId : "";
@@ -16,6 +16,7 @@ const GenericDialog = ({ title, description, open, onClose, theme, children }) =
1616
>
1717
<Stack
1818
gap={theme.spacing(2)}
19+
width={width}
1920
sx={{
2021
position: "absolute",
2122
top: "50%",
@@ -39,13 +40,15 @@ const GenericDialog = ({ title, description, open, onClose, theme, children }) =
3940
fontSize={16}
4041
color={theme.palette.primary.contrastText}
4142
fontWeight={600}
43+
marginBottom={theme.spacing(4)}
4244
>
4345
{title}
4446
</Typography>
4547
{description && (
4648
<Typography
4749
id={descriptionId}
4850
color={theme.palette.primary.contrastTextTertiary}
51+
marginBottom={theme.spacing(4)}
4952
>
5053
{description}
5154
</Typography>
@@ -64,6 +67,7 @@ GenericDialog.propTypes = {
6467
theme: PropTypes.object.isRequired,
6568
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node])
6669
.isRequired,
70+
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]),
6771
};
6872

6973
export { GenericDialog };

client/src/Hooks/inviteHooks.js

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,52 @@ const useGetInviteToken = () => {
1414
const clearToken = () => {
1515
setToken(undefined);
1616
};
17-
17+
const fetchToken = async (email, role) => {
18+
const response = await networkService.requestInvitationToken({ email, role });
19+
const token = response?.data?.data?.token;
20+
if (typeof token === "undefined") {
21+
throw new Error(t("inviteNoTokenFound"));
22+
}
23+
return token;
24+
};
1825
const getInviteToken = async ({ email, role }) => {
1926
try {
20-
const response = await networkService.requestInvitationToken({
21-
email,
22-
role,
23-
});
24-
const token = response?.data?.data?.token;
25-
if (typeof token === "undefined") {
26-
throw new Error(t("inviteNoTokenFound"));
27-
}
28-
27+
setIsLoading(true);
28+
const token = await fetchToken(email, role);
2929
let inviteLink = token;
3030

3131
if (typeof CLIENT_HOST !== "undefined") {
3232
inviteLink = `${CLIENT_HOST}/register/${token}`;
3333
}
34-
3534
setToken(inviteLink);
35+
return token;
36+
} catch (error) {
37+
setError(error);
38+
} finally {
39+
setIsLoading(false);
40+
}
41+
};
42+
43+
const addTeamMember = async (formData, role) => {
44+
try {
45+
setIsLoading(true);
46+
const token = await fetchToken(formData.email, role);
47+
const toSubmit = {
48+
...formData,
49+
inviteToken: token,
50+
};
51+
delete toSubmit.confirm;
52+
const responseRegister = await networkService.registerUser(toSubmit);
53+
return responseRegister;
3654
} catch (error) {
3755
setError(error);
56+
throw error;
3857
} finally {
3958
setIsLoading(false);
4059
}
4160
};
4261

43-
return [getInviteToken, clearToken, isLoading, error, token];
62+
return [getInviteToken, clearToken, isLoading, error, token, addTeamMember];
4463
};
4564

4665
export { useGetInviteToken };
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { useState } from "react";
2+
import Button from "@mui/material/Button";
3+
import Menu from "@mui/material/Menu";
4+
import MenuItem from "@mui/material/MenuItem";
5+
import { useTheme } from "@emotion/react";
6+
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
7+
import { useTranslation } from "react-i18next";
8+
import Proptypes from "prop-types";
9+
10+
const AddMemberMenu = ({ handleInviteOpen, handleIsRegisterOpen }) => {
11+
const [anchorEl, setAnchorEl] = useState(null);
12+
const open = Boolean(anchorEl);
13+
const { t } = useTranslation();
14+
const theme = useTheme();
15+
const handleClick = (event) => {
16+
setAnchorEl(event.currentTarget);
17+
};
18+
const handleClose = () => {
19+
setAnchorEl(null);
20+
};
21+
22+
return (
23+
<>
24+
<Button
25+
variant="contained"
26+
color="accent"
27+
endIcon={<ArrowDropDownIcon sx={{ color: theme.palette.secondary.light }} />}
28+
onClick={handleClick}
29+
>
30+
{t("teamPanel.addTeamMember.addMemberMenu")}
31+
</Button>
32+
<Menu
33+
anchorEl={anchorEl}
34+
open={open}
35+
onClose={handleClose}
36+
sx={{
37+
"& .MuiPaper-root": {
38+
minWidth: anchorEl?.offsetWidth || "auto",
39+
},
40+
}}
41+
>
42+
<MenuItem
43+
onClick={() => {
44+
handleClose();
45+
handleInviteOpen();
46+
}}
47+
>
48+
{t("teamPanel.inviteTeamMember")}
49+
</MenuItem>
50+
<MenuItem
51+
onClick={() => {
52+
handleClose();
53+
handleIsRegisterOpen(true);
54+
}}
55+
>
56+
{t("teamPanel.register")}
57+
</MenuItem>
58+
</Menu>
59+
</>
60+
);
61+
};
62+
63+
AddMemberMenu.propTypes = {
64+
handleInviteOpen: Proptypes.func.isRequired,
65+
handleIsRegisterOpen: Proptypes.func.isRequired,
66+
};
67+
68+
export default AddMemberMenu;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { useState } from "react";
2+
import { newOrChangedCredentials } from "../../../../../Validation/validation";
3+
import { useTranslation } from "react-i18next";
4+
const useAddTeamMember = () => {
5+
const { t } = useTranslation();
6+
const [errors, setErrors] = useState({});
7+
8+
const clearErrors = () => setErrors({});
9+
10+
const validateFields = (name, value, formData) => {
11+
const { error } = newOrChangedCredentials.validate(
12+
{ [name]: value },
13+
{ abortEarly: false, context: { password: formData.password } }
14+
);
15+
16+
setErrors((prev) => ({
17+
...prev,
18+
[name]: error?.details?.[0]?.message || "",
19+
}));
20+
};
21+
22+
const validateForm = (formData, role) => {
23+
const { error } = newOrChangedCredentials.validate(formData, {
24+
abortEarly: false,
25+
context: { password: formData.password },
26+
});
27+
const formErrors = {};
28+
if (error) {
29+
for (const err of error.details) {
30+
formErrors[err.path[0]] = err.message;
31+
}
32+
}
33+
if (!role[0] || role.length === 0) {
34+
formErrors.role = t(
35+
"teamPanel.registerTeamMember.auth.common.inputs.role.errors.empty"
36+
);
37+
}
38+
if (Object.keys(formErrors).length > 0) {
39+
setErrors(formErrors);
40+
return false;
41+
}
42+
setErrors({});
43+
return true;
44+
};
45+
46+
return { errors, setErrors, clearErrors, validateFields, validateForm };
47+
};
48+
export default useAddTeamMember;

0 commit comments

Comments
 (0)