Skip to content

Commit 6a67828

Browse files
committed
you can now add users to the github organization from your admin
1 parent 5f568f4 commit 6a67828

File tree

5 files changed

+129
-4
lines changed

5 files changed

+129
-4
lines changed

src/app/services/breathecode.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,13 @@ class BreatheCodeClient {
343343
payload
344344
);
345345
},
346+
addGithubUser: (payload) => {
347+
return axios.bcPost(
348+
"Invite",
349+
`${this.host}/auth/academy/github/user`,
350+
payload
351+
);
352+
},
346353
resendInvite: (user) =>
347354
axios.bcPut(
348355
"Invite",

src/app/views/admin/github-form/OrganizationUsers.jsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import bc from '../../../services/breathecode';
1616
import dayjs from 'dayjs';
1717
import config from '../../../../config.js';
1818
import { faLastfmSquare } from "@fortawesome/free-brands-svg-icons";
19+
import { PickCohortUserModal } from "./PickCohortUserModal";
1920

2021
const relativeTime = require('dayjs/plugin/relativeTime');
2122

@@ -56,7 +57,7 @@ const getStatus = (u) => {
5657

5758
const OrganizationUsers = ({ organization }) => {
5859
const [items, setItems] = useState([]);
59-
60+
const [ userToAdd, setUserToAdd] = useState(false);
6061

6162
const columns = [
6263
{
@@ -68,7 +69,7 @@ const OrganizationUsers = ({ organization }) => {
6869
return (
6970
<div>
7071
{item.user !== null && <h5 className="mb-0"><Link to={"/admissions/students/"+item.user.id}>{item.user.first_name + " " + item.user.last_name}</Link></h5>}
71-
<small>{item.username}</small>
72+
{item.username ? <small>{item.username}</small> : <small className="bg-danger px-1 border-radius-4">No username found</small>}
7273
</div>
7374
);
7475
},
@@ -105,8 +106,26 @@ const OrganizationUsers = ({ organization }) => {
105106
return data;
106107
}
107108

109+
const addToOrganization = async (cu) => {
110+
if(!cu) return false;
111+
112+
const result = await bc.auth().addGithubUser({ cohort: cu.cohort.id, user: cu.user.id });
113+
setUserToAdd(false);
114+
loadData();
115+
}
116+
108117
return (
109118
<Grid item md={12} className="mt-2">
119+
{ userToAdd == true && <PickCohortUserModal
120+
cohortQuery={{ stage: 'STARTED,PREWORK' }}
121+
cohortUserQuery={{ educational_status:'ACTIVE' }}
122+
onClose={(_cu) => addToOrganization(_cu)}
123+
/>}
124+
<div className="text-right">
125+
<Button variant="contained" color="primary" onClick={() => setUserToAdd(true)}>
126+
Add to the Github Organization
127+
</Button>
128+
</div>
110129
<SmartMUIDataTable
111130
title="All Github Organization Users"
112131
columns={columns}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import React, { useState } from 'react';
2+
import {
3+
Dialog,
4+
Button,
5+
DialogTitle,
6+
DialogActions,
7+
DialogContent,
8+
} from '@material-ui/core';
9+
import { AsyncAutocomplete } from 'app/components/Autocomplete';
10+
import bc from 'app/services/breathecode';
11+
12+
const defaultProps = {
13+
cohortQuery: {},
14+
cohorUserQuery: {},
15+
hint: null,
16+
onClose: null,
17+
open: true,
18+
};
19+
20+
export const PickCohortUserModal = ({
21+
defaultCohort=null,
22+
defaultCohortUser=null,
23+
cohortQuery,
24+
cohorUserQuery,
25+
hint,
26+
onClose,
27+
open
28+
}) => {
29+
30+
const [cohort, setCohort] = useState(defaultCohort)
31+
const [cohortUser, setCohortUser] = useState(defaultCohortUser)
32+
const [ error, setError ] = useState(null)
33+
34+
return (
35+
<>
36+
<Dialog
37+
open={open}
38+
onClose={() => onClose(false)}
39+
aria-labelledby="alert-dialog-title"
40+
aria-describedby="alert-dialog-description"
41+
fullWidth="md"
42+
>
43+
<DialogTitle className="ml-2" id="alert-dialog-title">
44+
Find a cohort and user
45+
</DialogTitle>
46+
<DialogContent>
47+
<AsyncAutocomplete
48+
defaultValue={defaultCohort}
49+
width="100%"
50+
onChange={(x) => setCohort(x)}
51+
label="Search for active or prework cohorts"
52+
value={cohort}
53+
getOptionLabel={(option) => `${option.name} (${option.stage})`}
54+
asyncSearch={async (searchTerm) => {
55+
const resp = await bc.admissions().getAllCohorts({ ...cohortQuery, like: searchTerm })
56+
if(resp.ok) return resp.data
57+
else setError("Error fetching cohorts")
58+
}}
59+
/>
60+
{cohort && <AsyncAutocomplete
61+
key={cohort.slug}
62+
defaultValue={defaultCohortUser}
63+
width="100%"
64+
onChange={(x) => setCohortUser(x)}
65+
label={`Search user in cohort ${cohort.name}`}
66+
value={cohortUser}
67+
debounced={false}
68+
getOptionLabel={(option) => `${option.user.first_name} ${option.user.last_name} - ${option.user.email}`}
69+
asyncSearch={async (searchTerm) => {
70+
let q = { ...cohorUserQuery, cohorts: cohort.slug };
71+
if(searchTerm) q.like = searchTerm;
72+
73+
const resp = await bc.admissions().getAllUserCohorts(q)
74+
if(resp.ok) return resp.data
75+
else setError("Error fetching cohort users")
76+
}}
77+
/>}
78+
{hint && <p className="my-2">{hint}</p>}
79+
</DialogContent>
80+
<DialogActions>
81+
<Button
82+
color="primary" tma
83+
variant="contained"
84+
autoFocus
85+
onClick={() => onClose(cohortUser)}
86+
>
87+
Select Cohort User
88+
</Button>
89+
</DialogActions>
90+
</Dialog>
91+
</>
92+
)
93+
}
94+
95+
PickCohortUserModal.defaultProps = defaultProps;

src/app/views/admin/github.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import React, { useEffect, useState } from "react";
2-
import { Grid } from "@material-ui/core";
2+
import { Grid, Button } from "@material-ui/core";
33
import { Alert, AlertTitle } from "@material-ui/lab";
44
import { useSelector } from 'react-redux';
55
import { Breadcrumb } from "../../../matx";
66
import bc from "../../services/breathecode";
7+
import { Link } from 'react-router-dom';
78
import OrganizationUsers from "./github-form/OrganizationUsers";
89
import GithubOrganization from "./github-form/GithubOrganization";
910
import { MatxLoading } from 'matx';
@@ -87,7 +88,7 @@ const GithubSettings = () => {
8788

8889
return (
8990
<div className="m-sm-30">
90-
<div className="mb-sm-30">
91+
<div className="flex flex-wrap justify-between mb-6">
9192
<Breadcrumb
9293
routeSegments={[
9394
{ name: "Admin", path: "/admin" },

src/index.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
.orange {
5656
background-color: rgb(255, 153, 0);
5757
}
58+
.bg-danger {
59+
background-color: rgb(241, 71, 71);
60+
}
5861
.text-warning{
5962
color: rgb(255, 153, 0);
6063
}

0 commit comments

Comments
 (0)