Skip to content
Snippets Groups Projects
Commit 547b9eb3 authored by Carl Valdemar Ebbesen's avatar Carl Valdemar Ebbesen
Browse files

Merge branch '13-update-overviewpage' into 'master'

Resolve "update overviewpage"

Closes #13

See merge request it2810-h21/team-11/gitlab-visualization!17
parents 45c7968a 36c46039
No related branches found
No related tags found
No related merge requests found
......@@ -15,13 +15,13 @@ function App() {
<LandingPage/>
</Route>
<Route exact path={"/overview"}>
<OverviewPage buttons={["commits","Issues"]} links={["/commits","/issues"]}/>
<OverviewPage/>
</Route>
<Route exact path={"/issues"}>
<OverviewPage buttons={["list","graphs"]} links={["/issuelist","/issuegraph"]}/>
<Route exact path={"/issue"}>
<OverviewPage/>
</Route>
<Route exact path={"/commits"}>
<OverviewPage buttons={["list","graphs"]} links={["/commitlist","/commitgraph"]}/>
<Route exact path={"/commit"}>
<OverviewPage/>
</Route>
<Route exact path={"/issuelist"}>
<IssuePage/>
......
src/assets/gitlab.jpeg

378 KiB

import axios from "axios";
const projectId = localStorage.getItem("projectId") ?? "11916"
const apiKey = localStorage.getItem("key") ?? "r74NY2kS_LprPFEobZxi";
const instance = axios.create({
baseURL: `https://gitlab.stud.idi.ntnu.no/api/v4/projects/${projectId}`,
headers: {"Authorization": `Bearer ${apiKey}`, "content_type":"application/json"},
})
export default instance;
\ No newline at end of file
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
border-radius: 16px;
background-color: lightslategray;
padding: 15px;
}
\ No newline at end of file
import React from 'react';
import style from "./stats.module.css";
interface StatsBoxProps {
content: string[]
}
const StatsBox: React.FC<StatsBoxProps> = ({content }) => {
return (
<div className={style.wrapper}>
{content.map(element => <p key={element} style={{margin: "10px auto", padding: "10px auto"}}>{element}</p>)}
</div>
);
};
export default StatsBox;
\ No newline at end of file
body {
background-color: #e1f0f6;
font-family: Epilogue;
font-size: 2.5vw;
}
.container {
......
......@@ -8,7 +8,6 @@ import ClipLoader from "react-spinners/ClipLoader";
const IssuePage = () => {
const {isLoading, error, data} = useGitlabApi(queryTypes.AllIssues)
console.log(data)
return (
<div className={styles.container}>
<h1 className={styles.headline}> Issues </h1>
......
button{
width: 20%;
}
input{
width: 75%;
padding: 10px 15px;
margin-bottom: 10px;
.inputField{
width: 50%;
height: 30px;
margin: 10px auto;
}
.inputWrapper{
position: absolute;
width: 400px;
height: 300px;
z-index: 15;
top: 50%;
left: 50%;
margin: -100px 0 0 -200px;
text-align: center;
width: 70%;
margin-left: 15%;
display: flex;
flex-direction: column;
}
form {
margin-top: 50px;
display: inline-block;
display: flex;
flex-direction: column;
}
.defaultButton {
position: absolute;
top: 0;
right: 0;
margin: auto;
padding: 5px;
cursor: pointer;
}
.submitButton {
background-color: lightgreen;
padding: 5px;
margin: auto;
cursor: pointer;
}
\ No newline at end of file
import React, {FC, useEffect, useState} from "react"
import React, { useEffect, useState} from "react"
import style from './landingPage.module.css';
import {useHistory} from 'react-router-dom';
import 'react-toastify/dist/ReactToastify.css';
......@@ -6,6 +6,7 @@ import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { ConnectionTest, queryTypes } from "../../utils/queryType";
import { useGitlabApi } from "../../utils/gitlab_api_service";
import visualization from "../../assets/gitlab.jpeg";
const LandingPage = () => {
......@@ -13,17 +14,18 @@ const LandingPage = () => {
const [key, setKey] = useState<string>(localStorage.getItem("key") ?? "");
const [projectId, setProjectId] = useState<string>(localStorage.getItem("projectId") ?? "");
const [query,setQuery] = useState<queryTypes>()
const {data,error} = useGitlabApi(query)
const {data, isLoading,error} = useGitlabApi(query)
const [disableButton, setDisableButton] = useState<boolean>(true);
const toast_response = (type:string) => {
if(type === "info"){
toast.info("Trying to reieve repository data");
toast.info("Checking if key and projectId is correct");
}
else if (type==="success") {
toast.success("Repository data recieved!");
toast.success("Success! Found the repository");
}
else {
toast.error("Could not get repository data. Try again");
toast.error("Could not find repository or wrong key. Try again");
}
}
......@@ -31,35 +33,51 @@ const LandingPage = () => {
localStorage.clear();
history.push("/overview");
}
useEffect(()=>{
if(!(projectId && key)) return;
const timer = setTimeout(()=>{
setDisableButton(true)
localStorage.setItem("projectId", projectId);
localStorage.setItem("key", key);
toast_response("info")
setQuery(queryTypes.Access);
}, 300)
return () =>{
setQuery(undefined);
clearTimeout(timer);
}
}, [key, projectId]);
useEffect(() => {
if(!error && query) {
if(!isLoading){
if(error){
toast_response("error")
setQuery(undefined)
}
if(data as ConnectionTest && query) {
else if(data as ConnectionTest) {
toast_response("success")
history.push("/overview")
setDisableButton(false);
}
}, [data, error, history, query]);
}
}, [data, error, isLoading]);
function handleSubmit(event: { preventDefault: () => void; }) {
event.preventDefault()
if (projectId && key) {
setQuery(queryTypes.Access)
toast_response("info")
localStorage.setItem("projectId", projectId);
localStorage.setItem("key", key);
}}
history.push("/overview")
}
return (
<div className={style.inputWrapper}>
<img alt="visualization" src={visualization} style={{width: "80%", margin: "30px auto" }}/>
<button className={style.defaultButton} onClick={()=> setDefaultValues()}>set default values</button>
<form onSubmit={handleSubmit}>
<input value = {projectId} type="Text" onChange={e => setProjectId(e.target.value)} id="ProjektIDInput"
<input className={style.inputField} value = {projectId} type="Text" onChange={e => setProjectId(e.target.value)} id="ProjektIDInput"
placeholder="ProjectId" required/>
<input value = {key} type="Text" onChange={e => setKey(e.target.value)} id="KeyInput"
<input className={style.inputField} value = {key} type="Text" onChange={e => setKey(e.target.value)} id="KeyInput"
placeholder="Key" required/>
<button type="submit">GO!</button>
<ToastContainer />
<button className={style.submitButton} type="submit" disabled={disableButton}>Use values</button>
<ToastContainer autoClose={3000} />
</form>
</div>
......
import React, {FC} from "react"
import {useHistory} from 'react-router-dom';
import style from './overview.module.css';
import React, { useState, useEffect } from 'react';
import { useHistory } from 'react-router';
import { useGitlabApi } from '../../utils/gitlab_api_service';
import { Languages, queryTypes } from '../../utils/queryType';
import StatsBox from '../../components/stats/statsBox';
import { ClipLoader } from 'react-spinners';
import { toast, ToastContainer } from 'react-toastify';
const OverviewPage = () => {
const slug = window.location.pathname;
const history = useHistory();
const {data, isLoading, error } = useGitlabApi(queryTypes.Languages);
interface IOverviewPage {
buttons: string[]
links: string[]
}
interface IButton {
name: string
link: string
}
const Button: FC<IButton> = (props) => {
let history = useHistory()
function handleClick() {
history.push(props.link)
}
return (
<div className={style.button} onClick={handleClick}>
<h4>
{props.name}
</h4>
</div>
)
<div className={style.wrapper}>
<h1>Stats:</h1>
{isLoading ? <ClipLoader loading={isLoading}/> :
<StatsBox content={data as Languages ? Object.entries(data as Languages).map(element => `${element[0]}: ${element[1]} %`): ["Loading ..."] } />
}
const OverviewPage: FC<IOverviewPage> = (props) => {
return (
<div className={style.outerWrapper}>
<div className={style.listwrapper}>
<ul>
{props.buttons.map((element, index) => <li><Button name={element} link={props.links[index]}/></li>)}
</ul>
<h2 style={{marginTop: "50px"}}>More info:</h2>
<div className={style.buttonWrapper}>
<button className={style.button} onClick= {() => history.push(slug=== "/overview" ? "/issue" : `${slug}graph`)}>
{slug=== "/overview" ? "Issues" : "Graph"}
</button>
<button className={style.button} onClick= {() => history.push(slug=== "/overview" ? "/commit" : `${slug}list`)}>
{slug=== "/overview" ? "Commits" : "List"}
</button>
</div>
</div>
)
}
);
};
export default OverviewPage;
\ No newline at end of file
.wrapper {
display: flex;
flex-direction: column;
width: 100%;
align-items: center;
}
.button{
position: relative;
background: gold;
margin: auto auto 30px;
width: 80%;
.buttonWrapper{
display: flex;
flex-direction: row;
justify-content: center;
width: 100%;
height: 40%;
}
.button{
background: #8ECAE6;
cursor: pointer;
font-size: 200%;
width: 250px;
height: 250px;
border-radius: 16px;
margin: 75px;
}
.button:hover,
......@@ -15,34 +27,3 @@
box-shadow: 0 0.5em 0.5em -0.4em;
transform: translateY(-0.25em);
}
\ No newline at end of file
.listwrapper{
min-width: 500px;
margin: auto;
border: 5px solid black;
top: 25%;
width: 70%;
height: 100%;
padding: 10px;
display: flex;
align-items: center;
}
.outerWrapper{
border: 5px solid red;
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-color: white;
}
ul {
padding: 0;
width: 100%;
list-style-type: none;
}
\ No newline at end of file
import { AxiosError } from "axios";
import axios, { AxiosError } from "axios";
import { useCallback, useEffect, useState } from "react";
import axios from "../axiosInstance";
import { Branch, Issue, Commit, ConnectionTest, queryTypes } from "./queryType";
import { Branch, Issue, Commit, ConnectionTest, queryTypes, Languages } from "./queryType";
export const useGitlabApi = (query: queryTypes|undefined) => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<AxiosError | undefined>();
const [data, setData] = useState<Issue[] | Commit[] | Branch[] | ConnectionTest>();
const [data, setData] = useState<Issue[] | Commit[] | Branch[] | ConnectionTest | Languages>();
const projectId = localStorage.getItem("projectId") ?? "11916"
const apiKey = localStorage.getItem("key") ?? "r74NY2kS_LprPFEobZxi";
const url = `https://gitlab.stud.idi.ntnu.no/api/v4/projects/${projectId}/${query}`;
const sendRequest = useCallback(async () => {
setIsLoading(true);
setError(undefined);
try{
const response = await axios.get(`/${query}`);
const response = await axios.get(url,
{headers: {"Authorization": `Bearer ${apiKey}`, "content_type":"application/json"}},);
setData(response.data);
setIsLoading(false);
}
catch (e){
console.log(e);
}}, [query]);
setError(e as AxiosError);
setIsLoading(false);
}}, [apiKey, url]);
useEffect(() => {
if(!query) return;
......
......@@ -3,15 +3,10 @@ export enum queryTypes {
MergedBranches = "repository/merged_branches/",
AllCommits = "repository/commits/",
AllIssues = "issues/",
issueStatistics = "issue_statistics/",
AllMembers = "members/",
Languages = "languages",
Access="access_requests",
}
export const getQueryString = (query: queryTypes, id: string = "") => {
return query.replace(':id', id);
};
export type User = {
id: String,
name: String,
......@@ -49,5 +44,10 @@ export type Branch = {
export type ConnectionTest = {
};
export type Languages = {
Typescript: number,
CSS: number,
HTML: number,
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment