Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eventtype #338

Open
wants to merge 39 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
c2e44c7
[Added new page for eventtype]
etolopez Jan 17, 2023
2b49c66
[Added two new views for EventTypes]
etolopez Feb 7, 2023
708ec90
[Made all changes, still working on it]
etolopez Feb 14, 2023
0f9430d
[Added the Modal inside EventypeDetails]
etolopez Feb 15, 2023
d1f04c6
[Simplified the JoinEvents file]
etolopez Feb 16, 2023
e7bb8eb
[Updates to eventtypes]
etolopez Feb 17, 2023
aec587a
[Finished Eventype pages]
etolopez Feb 21, 2023
fba1a99
[commented out the trash and the + for eventypes]
etolopez Feb 21, 2023
e078932
[Made changes to names]
etolopez Feb 27, 2023
9ca1155
[Changed flag position & add an Avatar image]
etolopez Feb 27, 2023
e3a0aae
[Made final changes]
etolopez Feb 28, 2023
23de318
[Added US flags]
etolopez Mar 9, 2023
6b10d58
[Changed flags to work]
etolopez Mar 9, 2023
e9038b9
[Added DE to languages]
etolopez Mar 14, 2023
fc4a561
[Added languages]
etolopez Mar 14, 2023
cab8647
[Added filter and language]
etolopez Mar 15, 2023
5762aaf
Merge pull request #349 from breatheco-de/development
alesanchezr Mar 21, 2023
5777a14
Merge pull request #350 from breatheco-de/development
alesanchezr Mar 21, 2023
0217dfa
Update ComposeAsset.js
tommygonzaleza Mar 27, 2023
585520f
Update ComposeAsset.js
tommygonzaleza Mar 27, 2023
38b6224
Merge branch 'development' of https://github.com/etolopez/admin into …
etolopez Mar 29, 2023
43166cf
Merge branch 'breatheco-de:master' into master
etolopez Mar 29, 2023
b54f10c
[Made Allowed_shared Creation]
etolopez Apr 5, 2023
caf7aa9
Merge branch 'development' of https://github.com/etolopez/admin into …
etolopez Apr 5, 2023
793fed5
Merge branch 'eventtype' of https://github.com/etolopez/admin into ev…
etolopez Apr 5, 2023
38dc73b
trying to create UI to add github org users directly
alesanchezr Apr 10, 2023
5f568f4
added devcontainers
alesanchezr Apr 10, 2023
6a67828
you can now add users to the github organization from your admin
alesanchezr Apr 11, 2023
34442b4
warning for invites
alesanchezr Apr 11, 2023
dceedb2
fixed github connection display error and now you can click on assets…
alesanchezr Apr 12, 2023
28b6e51
better github connection recomendation
alesanchezr Apr 12, 2023
4aa6c91
better explanation to github organization users
alesanchezr Apr 12, 2023
7f5cc13
Merge pull request #351 from breatheco-de/tommygonzaleza-patch-2
alesanchezr Apr 17, 2023
692f573
[Changing to Codespace]
etolopez Apr 18, 2023
356fffe
Merge branch 'breatheco-de:master' into eventtype
etolopez Apr 18, 2023
204ed6c
[Finished Event Types]
etolopez Apr 27, 2023
0e7f76c
Merge branch 'eventtype' of https://github.com/etolopez/admin into ev…
etolopez Apr 27, 2023
51ceba3
Merge branch 'master' of https://github.com/etolopez/admin into event…
etolopez Jun 23, 2023
cc86d9e
[Updated EvenType]
etolopez Jul 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
{
"name": "Node.js",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/javascript-node:0-16",

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "cp .env.example .env && touch /tmp/.npm-lock && npm install --legacy-peer-deps && rm /tmp/.npm-lock",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ yarn-error.log*

# Don't ignore gitpod files
!.gitignore
!.devcontainer/*
!.devcontainer
!.gitpod.yml
!.gitpod.Dockerfile
!.husky
Expand Down
8 changes: 4 additions & 4 deletions src/app/components/ConfirmAlert.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import PropTypes from 'prop-types';
const emptyCallback = () => {};
const defaultProps = {
onOpen: emptyCallback,
onClose: emptyCallback,
onClose: null,
isOpen: false,
setIsOpen: emptyCallback,
cancelText: 'Cancel',
Expand Down Expand Up @@ -46,7 +46,7 @@ const ConfirmAlert = ({
<Dialog
open={isOpen}
onClose={() => {
onClose();
onClose && onClose();
setIsOpen(false);
}}
aria-labelledby={titleTestId}
Expand All @@ -63,7 +63,7 @@ const ConfirmAlert = ({
</DialogContent>
) : <></>}
<DialogActions>
<Button
{onClose && <Button
data-cy={cancelButtonTestId}
onClick={() => {
onClose();
Expand All @@ -72,7 +72,7 @@ const ConfirmAlert = ({
color="primary"
>
{cancelText}
</Button>
</Button>}
<Button
color="primary"
type="submit"
Expand Down
6 changes: 0 additions & 6 deletions src/app/navigations.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,6 @@ export const navigations = [
iconText: "STA",
capabilities: ["read_invite"],
},
{
name: "Gitpod",
path: "/admin/gitpod",
iconText: "STA",
capabilities: ["get_gitpod_user"],
},
{
name: "Github",
path: "/admin/github",
Expand Down
62 changes: 55 additions & 7 deletions src/app/services/breathecode.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,17 @@ class BreatheCodeClient {
payload
),
getCertificates: () =>
axios.bcGet("Certificates", `${this.host}/admissions/syllabus`),
axios.bcGet(
"Certificates",
`${this.host}/admissions/syllabus`),
getAllSyllabus: () =>
axios.bcGet("Syllabus", `${this.host}/admissions/syllabus`),
axios.bcGet(
"Syllabus",
`${this.host}/admissions/syllabus`),
getAllAcademies: () =>
axios.bcGet(
"Academy",
`${this.host}/admissions/academy`),
getAllTimeZone: () =>
axios.bcGet(
"TimeZone",
Expand Down Expand Up @@ -343,6 +351,13 @@ class BreatheCodeClient {
payload
);
},
addGithubUser: (payload) => {
return axios.bcPost(
"Invite",
`${this.host}/auth/academy/github/user`,
payload
);
},
resendInvite: (user) =>
axios.bcPut(
"Invite",
Expand Down Expand Up @@ -803,12 +818,40 @@ class BreatheCodeClient {
"Academy event",
`${this.host}/events/academy/organizer`
),
addAcademyEventType: (payload) =>
axios.bcPost(
"Academy event type",
`${this.host}/events/academy/eventype`,
payload
),
getAcademyEventType: () =>
axios.bcGet(
"Event Type",
`${this.host}/events/academy/eventype?allow_shared_creation=true`
),
getAcademyEventTypeSlug: (slug) =>
axios.bcGet(
"Event Type Slug",
`${this.host}/events/academy/eventype/${slug}`
),
updateAcademyEventTypeSlug: (slug, payload) =>
axios.bcPut(
"Event Type Slug",
`${this.host}/events/academy/eventype/${slug}`,
payload
),
postAcademyEventOrganization: (payload) =>
axios.bcPost(
"Academy event",
`${this.host}/events/academy/organization`,
payload
),
postAcademyEventTypeVisibilitySetting: (payload, slug) =>
axios.bcPost(
"Academy event Type Visibility Setting",
`${this.host}/events/academy/eventype/${slug}/visibilitysetting`,
payload
),
putAcademyEventOrganization: (payload) =>
axios.bcPut(
"Academy event",
Expand All @@ -829,6 +872,16 @@ class BreatheCodeClient {
"Delete organizer",
`${this.host}/events/academy/organization/organizer/${org}`
),
deleteAcademyEventTypes: (org) =>
axios.bcDelete(
"Delete Eventtype",
`${this.host}/events/academy/`
),
deleteAcademyEventTypeVisibilitySetting: (slug, visibilityID) =>
axios.bcDelete(
"Delete Visibility Setting",
`${this.host}/events/academy/eventype/${slug}/visibilitysetting/${visibilityID}`
),
getEventbriteWebhook: (query) => {
const qs = serializeQuerystring(query);
return axios.bcGet(
Expand All @@ -842,11 +895,6 @@ class BreatheCodeClient {
},
getAcademyVenues: () =>
axios.bcGet("Venues", `${this.host}/events/academy/venues`),
getAcademyEventType: () =>
axios.bcGet(
"Event Type",
`${this.host}/events/academy/eventype`
),
downloadCSV: (query) => {
const qs = Object.keys(query)
.map((key) => `${key}=${query[key]}`)
Expand Down
51 changes: 48 additions & 3 deletions src/app/views/admin/github-form/OrganizationUsers.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline';
import DeleteOutlineRounded from '@material-ui/icons/DeleteOutlineRounded';
import AlarmOffRounded from '@material-ui/icons/AlarmOffRounded';
import { SmartMUIDataTable } from '../../../components/SmartDataTable';
import ConfirmAlert from '../../../components/ConfirmAlert';
import BulkAction from "./BulkAction"
import bc from '../../../services/breathecode';
import dayjs from 'dayjs';
import config from '../../../../config.js';
import { faLastfmSquare } from "@fortawesome/free-brands-svg-icons";
import { PickCohortUserModal } from "./PickCohortUserModal";
import HelpIcon from '../../../components/HelpIcon';

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

Expand Down Expand Up @@ -56,7 +59,8 @@ const getStatus = (u) => {

const OrganizationUsers = ({ organization }) => {
const [items, setItems] = useState([]);

const [ userToAdd, setUserToAdd] = useState(false);
const [ confirm, setConfirm] = useState(false);

const columns = [
{
Expand All @@ -67,8 +71,21 @@ const OrganizationUsers = ({ organization }) => {
const item = items[tableMeta.rowIndex];
return (
<div>
{item.user !== null && <h5 className="mb-0"><Link to={"/admissions/students/"+item.user.id}>{item.user.first_name + " " + item.user.last_name}</Link></h5>}
<small>{item.username}</small>
{item.user !== null ?
<h5 className="mb-0"><Link to={"/admissions/students/"+item.user.id}>{(item.user.first_name && item.user.first_name != '') ? item.user.first_name + " " + item.user.last_name : item.user.email}</Link></h5>
:
<h5 className="mb-0 text-danger">Not a 4Geeks user<HelpIcon message={`This user was found on github organization but no matching user was found on 4Geeks.com platform`} /></h5>
}
{item.github ?
<small className="px-1 py-2px bg-light-green text-green border-radius-4">{item.github.username}</small>
: item.username ? <>
<small className="bg-warning px-1 border-radius-4">Backup github found: {item.username}</small>
<HelpIcon message={`User has no github connected but we found a username, probably from a previous connection. We can work with this username but its recommended to ask user to re-connect.`} />
</>
: <>
<small className="bg-danger px-1 border-radius-4">No username found</small>
<HelpIcon message={`User needs to connect github`} />
</>}
</div>
);
},
Expand Down Expand Up @@ -105,8 +122,36 @@ const OrganizationUsers = ({ organization }) => {
return data;
}

const addToOrganization = async (cu) => {
if(!cu) return false;

const result = await bc.auth().addGithubUser({ cohort: cu.cohort.id, user: cu.user.id });
console.log("rrrresult", result);
if(result.status == 200){
setConfirm(true);
}
setUserToAdd(false);
loadData();
}

return (
<Grid item md={12} className="mt-2">
<ConfirmAlert
title={`User has been added to the invite queue. Keep in mind that invites are not sent in real time, instead, they are sent at 2AM UTC. Make sure the student has connected its GitHub account by then.`}
isOpen={confirm}
cancelText="I understand invites are processed later in batch"
onOpen={() => setConfirm(false)}
/>
{ userToAdd == true && <PickCohortUserModal
cohortQuery={{ stage: 'STARTED,PREWORK' }}
cohortUserQuery={{ educational_status:'ACTIVE' }}
onClose={(_cu) => addToOrganization(_cu)}
/>}
<div className="text-right">
<Button variant="contained" color="primary" onClick={() => setUserToAdd(true)}>
Add to the Github Organization
</Button>
</div>
<SmartMUIDataTable
title="All Github Organization Users"
columns={columns}
Expand Down
95 changes: 95 additions & 0 deletions src/app/views/admin/github-form/PickCohortUserModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React, { useState } from 'react';
import {
Dialog,
Button,
DialogTitle,
DialogActions,
DialogContent,
} from '@material-ui/core';
import { AsyncAutocomplete } from 'app/components/Autocomplete';
import bc from 'app/services/breathecode';

const defaultProps = {
cohortQuery: {},
cohorUserQuery: {},
hint: null,
onClose: null,
open: true,
};

export const PickCohortUserModal = ({
defaultCohort=null,
defaultCohortUser=null,
cohortQuery,
cohorUserQuery,
hint,
onClose,
open
}) => {

const [cohort, setCohort] = useState(defaultCohort)
const [cohortUser, setCohortUser] = useState(defaultCohortUser)
const [ error, setError ] = useState(null)

return (
<>
<Dialog
open={open}
onClose={() => onClose(false)}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
fullWidth="md"
>
<DialogTitle className="ml-2" id="alert-dialog-title">
Find a cohort and user
</DialogTitle>
<DialogContent>
<AsyncAutocomplete
defaultValue={defaultCohort}
width="100%"
onChange={(x) => setCohort(x)}
label="Search for active or prework cohorts"
value={cohort}
getOptionLabel={(option) => `${option.name} (${option.stage})`}
asyncSearch={async (searchTerm) => {
const resp = await bc.admissions().getAllCohorts({ ...cohortQuery, like: searchTerm })
if(resp.ok) return resp.data
else setError("Error fetching cohorts")
}}
/>
{cohort && <AsyncAutocomplete
key={cohort.slug}
defaultValue={defaultCohortUser}
width="100%"
onChange={(x) => setCohortUser(x)}
label={`Search user in cohort ${cohort.name}`}
value={cohortUser}
debounced={false}
getOptionLabel={(option) => `${option.user.first_name} ${option.user.last_name} - ${option.user.email}`}
asyncSearch={async (searchTerm) => {
let q = { ...cohorUserQuery, cohorts: cohort.slug };
if(searchTerm) q.like = searchTerm;

const resp = await bc.admissions().getAllUserCohorts(q)
if(resp.ok) return resp.data
else setError("Error fetching cohort users")
}}
/>}
{hint && <p className="my-2">{hint}</p>}
</DialogContent>
<DialogActions>
<Button
color="primary" tma
variant="contained"
autoFocus
onClick={() => onClose(cohortUser)}
>
Select Cohort User
</Button>
</DialogActions>
</Dialog>
</>
)
}

PickCohortUserModal.defaultProps = defaultProps;
5 changes: 3 additions & 2 deletions src/app/views/admin/github.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { useEffect, useState } from "react";
import { Grid } from "@material-ui/core";
import { Grid, Button } from "@material-ui/core";
import { Alert, AlertTitle } from "@material-ui/lab";
import { useSelector } from 'react-redux';
import { Breadcrumb } from "../../../matx";
import bc from "../../services/breathecode";
import { Link } from 'react-router-dom';
import OrganizationUsers from "./github-form/OrganizationUsers";
import GithubOrganization from "./github-form/GithubOrganization";
import { MatxLoading } from 'matx';
Expand Down Expand Up @@ -87,7 +88,7 @@ const GithubSettings = () => {

return (
<div className="m-sm-30">
<div className="mb-sm-30">
<div className="flex flex-wrap justify-between mb-6">
<Breadcrumb
routeSegments={[
{ name: "Admin", path: "/admin" },
Expand Down
Loading