Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2e81b6b

Browse files
committedJul 26, 2020
Merge remote-tracking branch 'origin/develop' into issue-473
# Conflicts: # client/src/pages/Search/Global.jsx
2 parents 1659a61 + ed7a9f7 commit 2e81b6b

File tree

36 files changed

+726
-674
lines changed

36 files changed

+726
-674
lines changed
 

‎client/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎client/public/favicon.ico

-1.95 KB
Binary file not shown.

‎client/src/Router.jsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export default function AppRouter() {
2222
position: "absolute",
2323
display: "flex",
2424
justifyContent: "center",
25+
alignItems: "center",
2526
height: "100vh",
2627
width: "100vw",
2728
backgroundColor: "white",
@@ -31,7 +32,11 @@ export default function AppRouter() {
3132
right: 0,
3233
}}
3334
>
34-
<img src={loader} alt="Loading" />
35+
<img
36+
style={{ height: "120px", width: "120px" }}
37+
src={loader}
38+
alt="Loading"
39+
/>
3540
</div>
3641
);
3742
}
Lines changed: 16 additions & 74 deletions
Loading

‎client/src/components/AddToGroupModal/index.jsx

Lines changed: 115 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { useEffect } from "react";
22
import PT from "prop-types";
33

44
import Button from "../Button";
@@ -10,6 +10,7 @@ import { useAuth0 } from "../../react-auth0-spa";
1010
import * as groupLib from "../../lib/groups";
1111

1212
import style from "./style.module.scss";
13+
import Axios from "axios";
1314

1415
export default function AddToGroupModal({ onCancel, updateUser, user }) {
1516
const apiClient = api();
@@ -21,34 +22,50 @@ export default function AddToGroupModal({ onCancel, updateUser, user }) {
2122
const [updatingGroups, setUpdatingGroups] = React.useState(false);
2223
const [userGroups, setUserGroups] = React.useState(user.groups);
2324
const [creatingGroup, setCreatingGroup] = React.useState(false);
25+
const cancelTokenSource = Axios.CancelToken.source();
26+
27+
/**
28+
* Component unmount trigger
29+
*/
30+
useEffect(() => {
31+
return () => {
32+
cancelTokenSource.cancel();
33+
};
34+
});
2435

2536
React.useEffect(() => {
2637
if (isLoading || !isAuthenticated) {
2738
return;
2839
}
2940

3041
(async () => {
31-
const groups = await groupLib.getGroups(apiClient, auth0User.nickname);
42+
const groups = await groupLib.getGroups(
43+
apiClient,
44+
auth0User.nickname,
45+
cancelTokenSource.token
46+
);
3247

33-
groups.myGroups.forEach((g, i, a) => {
34-
userGroups.forEach((ug, iug, aug) => {
35-
if (g.id === ug.id && !ug.isDeleted) {
36-
a[i] = { ...g, isSelected: true };
37-
}
48+
if (groups) {
49+
groups.myGroups.forEach((g, i, a) => {
50+
userGroups.forEach((ug, iug, aug) => {
51+
if (g.id === ug.id && !ug.isDeleted) {
52+
a[i] = { ...g, isSelected: true };
53+
}
54+
});
3855
});
39-
});
4056

41-
groups.otherGroups.forEach((g, i, a) => {
42-
userGroups.forEach((ug, iug, aug) => {
43-
if (g.id === ug.id && !ug.isDeleted) {
44-
a[i] = { ...g, isSelected: true };
45-
}
57+
groups.otherGroups.forEach((g, i, a) => {
58+
userGroups.forEach((ug, iug, aug) => {
59+
if (g.id === ug.id && !ug.isDeleted) {
60+
a[i] = { ...g, isSelected: true };
61+
}
62+
});
4663
});
47-
});
4864

49-
setMyGroups(groups.myGroups);
50-
setOtherGroups(groups.otherGroups);
51-
setIsLoadingGroups(false);
65+
setMyGroups(groups.myGroups);
66+
setOtherGroups(groups.otherGroups);
67+
setIsLoadingGroups(false);
68+
}
5269
})();
5370
// eslint-disable-next-line react-hooks/exhaustive-deps
5471
}, [isLoading, isAuthenticated, auth0User]);
@@ -106,6 +123,14 @@ export default function AddToGroupModal({ onCancel, updateUser, user }) {
106123
alert("Enter a group name");
107124
return;
108125
}
126+
if (groupName.length < 3) {
127+
alert("Group name must be more than three characters");
128+
return;
129+
}
130+
if (groupName.length > 150) {
131+
alert("Group name cannot exceed 150 characters");
132+
return;
133+
}
109134

110135
setCreatingGroup(true);
111136

@@ -131,59 +156,81 @@ export default function AddToGroupModal({ onCancel, updateUser, user }) {
131156
};
132157

133158
return (
134-
<Modal onCancel={onCancel}>
159+
<Modal
160+
onCancel={onCancel}
161+
className={style.container}
162+
overlayClassName={style.overlay}
163+
>
135164
<h1 className={style.title}>Add to Group</h1>
136-
<div className={style.searchRow}>
137-
<ZoomIcon className={style.zoomIcon} />
138-
<input
139-
className={style.search}
140-
onChange={({ target }) => {
141-
setFilter(target.value);
142-
setImmediate(() => target.focus());
143-
}}
144-
placeholder="Search or create group"
145-
value={filter}
146-
disabled={loadingGroups}
147-
/>
148-
<Button
149-
className={style.createButton}
150-
onClick={createGroup}
151-
disabled={creatingGroup}
152-
>
153-
{creatingGroup ? "Creating..." : "+ Create"}
154-
</Button>
155-
</div>
156-
<h3 className={style.subTitle}>
157-
My groups{loadingGroups && " (Loading...)"}
158-
</h3>
159-
<div className={style.groups}>
160-
{!loadingGroups &&
161-
myGroups
162-
.filter((g) => g.name.toLowerCase().includes(filter.toLowerCase()))
163-
.map((g) => (
164-
<Group
165-
checked={g.isSelected === true}
166-
group={g}
167-
key={g.id}
168-
onSwitch={() => switchSelected(g)}
169-
/>
170-
))}
171-
</div>
172-
<h3 className={style.subTitle}>
173-
Other Groups{loadingGroups && " (Loading...)"}
174-
</h3>
175165
<div className={style.groups}>
176-
{!loadingGroups &&
177-
otherGroups
178-
.filter((g) => g.name.toLowerCase().includes(filter.toLowerCase()))
179-
.map((g) => (
180-
<Group
181-
checked={g.isSelected === true}
182-
group={g}
183-
key={g.id}
184-
onSwitch={() => switchSelected(g)}
185-
/>
186-
))}
166+
<div className={style.searchRow}>
167+
<ZoomIcon className={style.zoomIcon} />
168+
<input
169+
className={style.search}
170+
onChange={({ target }) => {
171+
setFilter(target.value);
172+
setImmediate(() => target.focus());
173+
}}
174+
placeholder="Search or create group"
175+
value={filter}
176+
disabled={loadingGroups}
177+
/>
178+
<Button
179+
className={style.createButton}
180+
onClick={createGroup}
181+
disabled={creatingGroup}
182+
>
183+
{creatingGroup ? "Creating..." : "+ Create"}
184+
</Button>
185+
</div>
186+
<h3 className={style.subTitle}>
187+
My groups{loadingGroups && " (Loading...)"}
188+
</h3>
189+
<div>
190+
{!loadingGroups &&
191+
myGroups
192+
.filter((g) =>
193+
g.name.toLowerCase().includes(filter.toLowerCase())
194+
)
195+
.map((g) => (
196+
<Group
197+
checked={g.isSelected === true}
198+
group={g}
199+
key={g.id}
200+
onSwitch={() => switchSelected(g)}
201+
/>
202+
))}
203+
</div>
204+
{myGroups.filter((g) =>
205+
g.name.toLowerCase().includes(filter.toLowerCase())
206+
).length === 0 &&
207+
!loadingGroups && (
208+
<div className={style.message}>No results found</div>
209+
)}
210+
<h3 className={style.subTitle}>
211+
Other Groups{loadingGroups && " (Loading...)"}
212+
</h3>
213+
<div>
214+
{!loadingGroups &&
215+
otherGroups
216+
.filter((g) =>
217+
g.name.toLowerCase().includes(filter.toLowerCase())
218+
)
219+
.map((g) => (
220+
<Group
221+
checked={g.isSelected === true}
222+
group={g}
223+
key={g.id}
224+
onSwitch={() => switchSelected(g)}
225+
/>
226+
))}
227+
</div>
228+
{otherGroups.filter((g) =>
229+
g.name.toLowerCase().includes(filter.toLowerCase())
230+
).length === 0 &&
231+
!loadingGroups && (
232+
<div className={style.message}>No results found</div>
233+
)}
187234
</div>
188235
<div className={style.buttons}>
189236
<Button onClick={onCancel} disabled={updatingGroups || creatingGroup}>

‎client/src/components/AddToGroupModal/style.module.scss

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
@import "../../styles/mixins";
22

3+
.container {
4+
z-index: 1100;
5+
}
6+
7+
.overlay {
8+
z-index: 1010;
9+
}
10+
311
.buttons {
412
display: flex;
513
justify-content: flex-end;
@@ -36,7 +44,7 @@
3644

3745
.groups {
3846
margin: 0 -30px;
39-
max-height: 150px;
47+
max-height: calc(95vh - 157px);
4048
overflow-y: auto;
4149
}
4250

@@ -60,10 +68,12 @@
6068
.searchRow {
6169
display: flex;
6270
position: relative;
71+
margin: 0 30px;
6372
}
6473

6574
.subTitle {
6675
@include h3;
76+
margin-left: 30px;
6777
}
6878

6979
.title {
@@ -76,3 +86,9 @@
7686
left: 10px;
7787
top: 10px;
7888
}
89+
90+
.message {
91+
color: $textColor2;
92+
font: 400 12pt/1.25 Inter;
93+
margin-left: 30px;
94+
}

0 commit comments

Comments
 (0)
This repository has been archived.