Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 9da29ef

Browse files
authored
Merge pull request #84 from cagdas001/dev
feat: add roles page
2 parents 1783207 + a58e35c commit 9da29ef

File tree

26 files changed

+1721
-13
lines changed

26 files changed

+1721
-13
lines changed
Loading
+22
Loading

src/assets/images/icon-search.svg

+18
Loading

src/components/Icons/Roles/index.jsx

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from "react";
2+
import PT from "prop-types";
3+
import cn from "classnames";
4+
import IconWrapper from "components/IconWrapper";
5+
import IconRoleManagement from "../../../assets/images/icon-menu-item-roles.svg";
6+
import styles from "./styles.module.scss";
7+
8+
/**
9+
* Displays a "role management" icon used in navigation menu.
10+
*
11+
* @param {Object} props component props
12+
* @param {string} [props.className] class name added to root element
13+
* @param {boolean} [props.isActive] a flag indicating whether the icon is active
14+
* @returns {JSX.Element}
15+
*/
16+
const Roles = ({ className, isActive = false }) => (
17+
<IconWrapper
18+
className={cn(styles.container, className, { [styles.isActive]: isActive })}
19+
>
20+
<IconRoleManagement />
21+
</IconWrapper>
22+
);
23+
24+
Roles.propTypes = {
25+
className: PT.string,
26+
isActive: PT.bool,
27+
};
28+
29+
export default Roles;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.container {
2+
svg {
3+
display: block;
4+
width: auto;
5+
height: 100%;
6+
7+
path {
8+
fill: #7f7f7f;
9+
}
10+
}
11+
12+
&.isActive {
13+
svg {
14+
path {
15+
fill: #06d6a0;
16+
}
17+
}
18+
}
19+
}

src/components/Sidebar/index.jsx

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import NavMenu from "components/NavMenu";
55
import styles from "./styles.module.scss";
66
import WorkPeriods from "components/Icons/WorkPeriods";
77
import Freelancers from "components/Icons/Freelancers";
8+
import Roles from "components/Icons/Roles";
89
import { APP_BASE_PATH } from "../../constants";
910

1011
/**
@@ -38,6 +39,11 @@ const NAV_ITEMS = [
3839
label: "Freelancers",
3940
path: `${APP_BASE_PATH}/freelancers`,
4041
},
42+
{
43+
icon: Roles,
44+
label: "Roles",
45+
path: `${APP_BASE_PATH}/roles`,
46+
},
4147
];
4248

4349
export default Sidebar;

src/components/SearchHandleField/index.jsx renamed to src/components/Typeahead/index.jsx

+21-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React, { useCallback, useRef, useState } from "react";
22
import PT from "prop-types";
33
import cn from "classnames";
4+
import get from "lodash/get";
45
import throttle from "lodash/throttle";
56
import Select, { components } from "react-select";
6-
import { getMemberSuggestions } from "services/teams";
77
import { useUpdateEffect } from "utils/hooks";
88
import styles from "./styles.module.scss";
99

@@ -75,9 +75,11 @@ const selectComponents = {
7575
* @param {function} [props.onInputChange] function called when input value changes
7676
* @param {function} [props.onBlur] function called on input blur
7777
* @param {string} props.value input value
78+
* @param {function} props.getSuggestions the function to get suggestions
79+
* @param {string} props.targetProp the target property of the returned object from getSuggestions
7880
* @returns {JSX.Element}
7981
*/
80-
const SearchHandleField = ({
82+
const Typeahead = ({
8183
className,
8284
id,
8385
name,
@@ -87,6 +89,8 @@ const SearchHandleField = ({
8789
onBlur,
8890
placeholder,
8991
value,
92+
getSuggestions,
93+
targetProp,
9094
}) => {
9195
const [inputValue, setInputValue] = useState(value);
9296
const [isLoading, setIsLoading] = useState(false);
@@ -165,11 +169,15 @@ const SearchHandleField = ({
165169
return;
166170
}
167171
setIsLoading(true);
168-
const options = await loadSuggestions(value);
172+
setIsMenuOpen(true);
173+
const options = await loadSuggestions(
174+
getSuggestions,
175+
value,
176+
targetProp
177+
);
169178
if (!isChangeAppliedRef.current) {
170179
setOptions(options);
171180
setIsLoading(false);
172-
setIsMenuOpen(true);
173181
}
174182
},
175183
300,
@@ -223,17 +231,17 @@ const SearchHandleField = ({
223231
);
224232
};
225233

226-
const loadSuggestions = async (inputValue) => {
234+
const loadSuggestions = async (getSuggestions, inputValue, targetProp) => {
227235
let options = [];
228236
if (inputValue.length < 3) {
229237
return options;
230238
}
231239
try {
232-
const res = await getMemberSuggestions(inputValue);
233-
const users = res.data.slice(0, 100);
240+
const res = await getSuggestions(inputValue);
241+
const items = res.data.slice(0, 100);
234242
let match = null;
235-
for (let i = 0, len = users.length; i < len; i++) {
236-
let value = users[i].handle;
243+
for (let i = 0, len = items.length; i < len; i++) {
244+
let value = get(items[i], targetProp);
237245
if (value === inputValue) {
238246
match = { value, label: value };
239247
} else {
@@ -250,7 +258,7 @@ const loadSuggestions = async (inputValue) => {
250258
return options;
251259
};
252260

253-
SearchHandleField.propTypes = {
261+
Typeahead.propTypes = {
254262
className: PT.string,
255263
id: PT.string.isRequired,
256264
size: PT.oneOf(["medium", "small"]),
@@ -260,6 +268,8 @@ SearchHandleField.propTypes = {
260268
onBlur: PT.func,
261269
placeholder: PT.string,
262270
value: PT.oneOfType([PT.number, PT.string]),
271+
getSuggestions: PT.func,
272+
targetProp: PT.string,
263273
};
264274

265-
export default SearchHandleField;
275+
export default Typeahead;

src/constants/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export const WORK_PERIODS_PATH = `${APP_BASE_PATH}/work-periods`;
88

99
export const FREELANCERS_PATH = `${APP_BASE_PATH}/freelancers`;
1010

11+
export const ROLES_PATH = `${APP_BASE_PATH}/roles`;
12+
1113
export const TAAS_BASE_PATH = "/taas";
1214

1315
export const ADMIN_ROLES = ["bookingmanager", "administrator"];

src/root.component.jsx

+3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import store from "store";
55
import { disableSidebarForRoute } from "@topcoder/micro-frontends-navbar-app";
66
import WorkPeriods from "routes/WorkPeriods";
77
import Freelancers from "routes/Freelancers";
8+
import Roles from "routes/Roles";
89
import {
910
APP_BASE_PATH,
1011
FREELANCERS_PATH,
1112
WORK_PERIODS_PATH,
13+
ROLES_PATH,
1214
} from "./constants";
1315
import "styles/global.scss";
1416

@@ -23,6 +25,7 @@ export default function Root() {
2325
<Redirect from={APP_BASE_PATH} to={WORK_PERIODS_PATH} exact noThrow />
2426
<WorkPeriods path={WORK_PERIODS_PATH} />
2527
<Freelancers path={FREELANCERS_PATH} />
28+
<Roles path={ROLES_PATH} />
2629
</Router>
2730
</Provider>
2831
);

0 commit comments

Comments
 (0)